首先来看一段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"; }