session过期以后,需要重新登陆,struts2拦截器或过滤器可以验证session是否还存在,如果不存在,则跳转到登录页面,或其他页面。其中拦截器是动态拦截action调用的对象,开发者可以定义在一个action执行前后执行的代码,也可以在一个action执行前阻止其执行;过滤器是在jsp页面中获取session,如果获取不到,再进行相应的处理。
struts2提供了种类丰富的拦截器,在struts-default.xml里面有关于默认的拦截器和拦截器链的配置,拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。
简单来说,就是编写拦截器类和在struts的配置文件里定义拦截器、拦截器栈。
自定义拦截器
1.1 实现拦截器类
所有的Struts2的拦截器都直接或间接实现接口com.opensymphony.xwork2.interceptor.Interceptor。该接口提供了三个方法:
1)void init();在该拦截器被初始化之后,在该拦截器执行拦截之前,系统回调该方法。对于每个拦截器而言,此方法只执行一次。
2)void destroy();该方法跟init()方法对应。在拦截器实例被销毁之前,系统将回调该方法。
3)String intercept(ActionInvocationinvocation)throwsException;该方法是用户需要实现的拦截动作。该方法会返回一个字符串作为逻辑视图。
除此之外,继承类com.opensymphony.xwork2.interceptor.AbstractInterceptor是更简单的一种实现拦截器类的方式,因为此类提供了init()和destroy()方法的空实现,这样我们只需要实现intercept方法。
package com.tc.bookRoom.interceptor;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.tc.bookRoom.common.service.bean.UserBean;
@SuppressWarnings("serial")
public class LoginedCheckInterceptor extends AbstractInterceptor {
@Override
public String intercept(ActionInvocation ai) throws Exception {
String url = ServletActionContext.getRequest().getRequestURL()
.toString();//获取链接的URL
HttpServletResponse response = ServletActionContext.getResponse();
response.setHeader("Pragma", "No-cache");//清除IE缓存
response.setHeader("Cache-Control", "no-cache");//同上
response.setHeader("Cache-Control", "no-store");
response.setDateHeader("Expires", 0);
ActionContext ctx = ActionContext.getContext();
UserBean uBean1 = (UserBean) ctx.getSession().get("user");//获取用户的session
UserBean uBean2 = (UserBean) ctx.getSession().get("admin");//获取管理员的session
if (url.indexOf("checkUser.action") != -1 || url.indexOf("LogOut.action") != -1) {//排除登录和登出的action
return ai.invoke();
} else if (uBean1 == null && uBean2 == null) {
return "tologin";
} else {
return ai.invoke();
}
}
}
注:如果项目的结构搭建的好的话,拦截器类是没有这么麻烦的,直接获取session,判断是否为空,再进行处理就可以了。我是项目搭建的不好,才需要对url进行判断,汗。。。至于清空缓存,在jsp里面也可以实现。
1.2使用自定义拦截器
两个步骤:1)通过<interceptor…>元素来定义拦截器。2)通过<interceptor-ref…>元素来使用拦截器
因为我项目里面都需要对session进行判断,所以我将实现部分写在总配置文件里,并使用了默认拦截器。
<package name="struts-interceptor" extends="struts-default" namespace="/">
<!-- 配置自定义拦截器LoginedCheckInterceptor -->
<interceptors>
<interceptor name="loginedCheck"
class="com.tc.bookRoom.interceptor.LoginedCheckInterceptor" />
<!-- 默认的必须放在最下面! -->
<interceptor-stack name="mystack">
<interceptor-ref name="loginedCheck" />
<interceptor-ref name="defaultStack" />
</interceptor-stack>
</interceptors>
<!-- 默认拦截器,此包下所有的ACTION将都被拦截。如果ACTION再定义了拦截器,则失效 -->
<default-interceptor-ref name="mystack"></default-interceptor-ref>
<!-- 定义全局result -->
<global-results>
<!-- 定义名为exception的全局result -->
<result name="exception">/login.jsp</result>
<result name="tologin">/login.jsp</result>
</global-results>
<!-- 定义全局异常映射 -->
<global-exception-mappings>
<!-- 捕捉到Exception异常(所有异常)时跳转到exception所命名的视图上 -->
<exception-mapping exception="java.lang.Exception"
result="exception" />
</global-exception-mappings>
</package>
然后将总文件下面的子文件配置中的extends="struts-default"改成extends="struts-interceptor",就可以用了。