解决思路:
1. 后台添加拦截器,判断session是否过期,过期返回一个标识。
2. 前台捕获到这个请求返回的值,最好在一个统一的地方捕获。一般选择Ext.Ajax的requestcomplete或者requestexception事件。
后来发现spring security原来有sessiontimeout配置的地方,当session超时时,会自动触发。
解决代码:
1. web.xml文件中加入
<session-config> <session-timeout>1</session-timeout> </session-config>
这个是配置session的过期的时间,单位是分钟,必须是整数。这里设置1分钟,方便测试
2. spring-config-security.xml文件中配置session超时的触发函数
<sec:session-management invalid-session-url="/sessiontimeout.do" ></sec:session-management>
这里可以直接配置invalid-session-url="/login.jsp",这里我配置了一个处理函数,因为要解决异步处理的情况
3.编写超时处理函数
@RequestMapping("/sessiontimeout.do")
public void sessionTimeout(HttpServletRequest request,HttpServletResponse response) throws IOException {
String requestUrl = request.getRequestURI();
if (request.getHeader("x-requested-with") != null
&& request.getHeader("x-requested-with").equalsIgnoreCase(
"XMLHttpRequest")) { // ajax 超时处理
response.setHeader("sessionstatus", "timeout");
PrintWriter out = response.getWriter();
out.print("{timeout:true}");
out.flush();
out.close();
}else { // http 超时处理
response.sendRedirect(request.getContextPath() + "/login.do");
}
}
4. 前台统一监听处理函数
Ext.Ajax.on('requestcomplete',function(conn, response, options, eOpts){
if(response.getResponseHeader("sessionstatus")=='timeout'){
alert("登入超时,系统将自动跳转到登陆页面,请重新登入!");
window.location = __ctxPath + "/login.do"; //如重定向到登陆页面
}
});
参考文献:
http://blog.youkuaiyun.com/fly2749/article/details/8702855
http://yxkelsey.iteye.com/blog/618129
http://blog.youkuaiyun.com/awe5566/article/details/10201671
后续:
1.spring-mvc异常处理拦截器
public class SessionTimeoutInterceptor implements HandlerInterceptor {
private List<String> allowUrls;
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
String requestUrl = request.getRequestURI();
/**
* 对所有的请求,*.f进行拦截
*/
if(requestUrl.indexOf(".f")!=-1){
/**
* 登录页login.do不进行拦截
*/
for(String url : allowUrls) {
if(requestUrl.endsWith(url)) {
return true;
}
}
Object obj = request.getSession().getServletContext().getAttribute("user");
if(obj != null) {
return true;
}else {
response.setHeader("sessionstatus", "timeout");
return false;
}
}else{
return true;
}
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
public List<String> getAllowUrls() {
return allowUrls;
}
public void setAllowUrls(List<String> allowUrls) {
this.allowUrls = allowUrls;
}
}
2.拦截器配置
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/*/*" />
<bean class="*.SessionTimeoutInterceptor" >
<property name="allowUrls">
<list>
<value>/login.do</value>
</list>
</property>
</bean>
</mvc:interceptor>
</mvc:interceptors>
<!-- exception handler 统一异常处理-->
<bean id="handlerExceptionResolver"
class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver" >
<property name="exceptionMappings">
<props>
<prop key="*.CustomeException">redirect:/sessiontimeout.do</prop>
</props>
</property>
</bean>