解决思路:
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.csdn.net/fly2749/article/details/8702855
http://yxkelsey.iteye.com/blog/618129
http://blog.csdn.net/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>