先贴贴代码
struts.xml中代码:
<!-- 自定义拦截器 start -->
<interceptors>
<!-- session拦截器-->
<interceptor name="sessionout"
class="interceptor.AdminInterceptor">
<param name="includeMethods">list*,delete*,update*,save*,find*</param>
</interceptor>
<!-- 拦截器栈 -->
<interceptor-stack name="mystack">
<!-- session拦截-->
<interceptor-ref name="sessionout" />
<interceptor-ref name="defaultStack" /> <!-- 默认拦截器 -->
</interceptor-stack>
</interceptors>
<!-- 自定义拦截器 end -->
<global-results>
<!-- 当返回login视图名时,转入/login.jsp页面 -->
<result name="login">/partials/login.jsp</result>
</global-results>
interceptor.AdminInterceptor类代码:
public class AdminInterceptor extends AbstractInterceptor {
@Override
public String intercept(ActionInvocation actionInvocation) throws Exception {
// 取得请求的URL
String tempUrl=null;
String url = ServletActionContext.getRequest().getRequestURL().toString();
HttpServletResponse response = ServletActionContext.getResponse();
HttpServletRequest httpReq=(HttpServletRequest)ServletActionContext.getRequest();
//HttpServletResponse httpResp=(HttpServletResponse)ServletActionContext.getResponse();
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Cache-Control", "no-store");
response.setDateHeader("Expires", 0);
User loginUser = null;
// 对登录与注销请求直接放行,不予拦截
if (url.indexOf("Login") != -1 || url.indexOf("Out") != -1) {
return actionInvocation.invoke();
} else {
// 验证Session是否过期
if (!ServletActionContext.getRequest().isRequestedSessionIdValid()) {
// session过期,转向session过期提示页,最终跳转至登录页面
System.out.println("session过期");
return "login";
} else {
loginUser = (User) ServletActionContext.getRequest().getSession().getAttribute("adminuser");
// 验证是否已经登录
if (loginUser == null) {
if (httpReq.getHeader("x-requested-with") != null
&& httpReq.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")){
//如果是ajax请求响应头会有,x-requested-with
response.setHeader("sessionstatus", "timeout");// 在响应头设置session状态
//return false;
}
tempUrl="partials/login.jsp";
// 尚未登录,跳转至登录页面
System.out.println("尚未登录,跳转至登录页面");
RequestDispatcher rd=httpReq.getRequestDispatcher(tempUrl);
rd.forward(httpReq,response);
return "login";
} else {
return actionInvocation.invoke();
}
}
}
}
}
JS代码:
define(['jquery'], function ($) {
//全局的ajax访问,处理ajax清求时sesion超时
$.ajaxSetup( {
contentType : "application/x-www-form-urlencoded;charset=utf-8",
complete : function(XMLHttpRequest, textStatus) {
var sessionstatus = XMLHttpRequest
.getResponseHeader("sessionstatus"); //通过XMLHttpRequest取得响应头,sessionstatus,
if (sessionstatus == "timeout") {
//如果超时就处理 ,指定要跳转的页面
window.location.href = ctx + "/login.html";
}
}
});
});
与平常写的拦截器不同的地方是跳转的实现,现在很多都是用异步来请求数据,之前的写法是拦截到了异步的方法之后不会跳转。
以上大概原理是在拦截器类中设置如果用户的session超时或者已经销毁了,而且被拦截的请求是ajax请求,就设置session的状态为超时(response.setHeader("sessionstatus", "timeout");//在响应头设置session状态),同时在发出请求的JSP页面监控session是否超时,超时就跳转登录界面(window.location.href = ctx + "/login.html";)。
对于拦截异步请求跳转不知大牛们有没有更好的方法,希望能指点。