先看一段代码:
@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";
}
}
在上面代码中,如果用户登陆失败的话,我们用addActionMessage把登录失败的消息add到actionmessagge中,这个actionmessage如果默认的话,生命周期是request周期的,如果认证失败后转到一个jsp页面,在这个jsp页面中用<s:actionmessage />是可以正常显示的,但是如果我们redirect转向的是一个LoginAction,再从LoginAction转到login.jsp,想在login.jsp中用<s:actionmessage />显示actionmessage,你会发现这时actionmessage是不会显示出来的,分析一下,原来是因为在redirect的时候,actionmessage在request中已经被丢失了。redirect操作是会挂失掉request里面的东西的。
那么如何保存这个actionmessage呢?查看了一下struts2的struts.xml,发现有一个名为store的拦截器,类名为org.apache.struts2.interceptor.MessageStoreInterceptor,这个拦截器的作用就是将我们放在ActionMessaage中的信息保存到session中,而不丢失,那么接下来的问题就好解决了。
上面的AdminLoginAction是在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>
这一下再试,actionmessage已经乖乖的显示在login.jsp页面了。有一个注意的地方就是登陆失败时,转到下面的这个url:
@Action(value="/admin/login",results={@Result(name="login", location="/admin/login.jsp", type="dispatcher")} )
public String execute(){
return "login";
}
,这里的type一定要是dispatcher,不能是redirect,否则actionmessage会在这里再次丢失的。
呵呵,就到这里吧,关于这个问题,网上有很多朋友都遇到过的,我在这里把我的解决方案写下来,希望能帮助到他人。