首先来看一段ACTION代码
@ParentPackage(value="noneedlogin")
public class AdminLoginAction extends ActionSupport
implements SessionAware,ModelDriven<AdminUser>{
@Action
(
value="/admin/adminlogin",
results={
@Result(name="success", location="/admin/admin-login-ok.jsp", type="redirect"),
@Result(name="login-failed", location="/admin/login", type="redirect")
}
)
public String login() throws IOException{
if(validatecaptchaCode()){
AdminUser adminUser = adminUserManager.findByUserName(entity.getUserName());
String md5String = DigestUtils.md5Hex(entity.getPassword());
if(adminUser==null ||(!md5String.equals( adminUser.getPassword() )) ){
log.error("用户名或密码有误,请重请登录");
addActionMessage("用户名或密码有误,请重请登录");
return "login-failed";
}
log.info("login ok!add to session-------------");
SessionFactory.addAdminUserSession(session,adminUser);
String lastVisitUrl = SessionFactory.getLastAdminVistedUrl(session);
if(lastVisitUrl!=null && lastVisitUrl.length()>2){
log.info("last visited :"+lastVisitUrl);
ServletActionContext.getResponse().sendRedirect(lastVisitUrl);
return null;
}
return this.SUCCESS;
}else{
log.error("验证码有误,请重请登录");
addActionMessage("验证码有误,请重请登录");
return "login-failed";
}
}
这里我们只关注ActionMessage,看到没有无论是成功还是失败都是redirect方式的跳转,我们这里所说的redirect传递丢失ActionMessage问题指的是@Result(name="login-failed", location="/admin/login", type="redirect")这种
方式,这种方式不会直接转换到一个xx.jsp上,而是中间经过了一个其他的Action,大家都知道redirect方式传递关于保存在request请求域中的数值都会丢失,多以我们要做的就是使这个值保存到SESSION中去
具体解决方案
上边的Action类是在noneedlogin包类,我们要做的就是在struts.xml中noneedlogin包的默认拦截器中加入store拦截器
<package name="noneedlogin" extends="convention-default" > <interceptors> <interceptor-stack name="storeStack"> <interceptor-ref name="store"> <param name="operationMode">AUTOMATIC</param> </interceptor-ref> <interceptor-ref name="paramsPrepareParamsStack" /> </interceptor-stack> </interceptors> <default-interceptor-ref name="storeStack" /> </package>
当然这不是唯一的写法,以一种写法还可以是下面这样的
<constant name="struts.convention.default.parent.package" value="crud-default" /> <constant name="struts.convention.package.locators" value="web" /> <constant name="struts.convention.package.locators.basePackage" value="com.javacrazyer.demo" /> <!-- 用于CRUD Action的parent package --> <package name="crud-default" extends="convention-default, json-default"> <!-- 基于paramsPrepareParamsStack, 增加store interceptor保证actionMessage在redirect后不会丢失 --> <interceptors> <interceptor-stack name="crudStack"> <interceptor-ref name="store"> <param name="operationMode">AUTOMATIC</param> </interceptor-ref> <interceptor-ref name="paramsPrepareParamsStack" /> </interceptor-stack> </interceptors> <default-interceptor-ref name="crudStack" /> </package>
好了上面说到本文章解决方案是针对@Result(name="login-failed", location="/admin/login", type="redirect")而
不是针对@Result(name="success", location="/admin/admin-login-ok.jsp", type="redirect"),这是因为在
直接以redirect方式跳转到JSP页面的这种,本方案是解决不了问题的,所以如果是直接跳转到JSP页面type类型就要改成是dispatcher,即如下方式
@Action(value="/admin/login",results={@Result(name="login", location="/admin/login.jsp", type="dispatcher")} )
public String execute(){
return "login";
}