使用springmvc 拦截器 处理 session 过期问题,及使用ajaxSetup()方法统一处理ajax请求跳转问题
-
在springmvc.xml 中配置拦截器,注意springmvc 的约束文件必须在3.2
以上(http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd),否则将会报错。mapping path=""拦截所有的请求,exclude-mapping对一些静态资源设置不拦截,AccessInterceptor自定义拦截器类,需继承HandlerInterceptor。<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**/*"/> <mvc:exclude-mapping path="/login/p13Login"/> <mvc:exclude-mapping path="/login/captcha"/> <mvc:exclude-mapping path="/login/testLogin"/> <mvc:exclude-mapping path="/**/*.html"/> <mvc:exclude-mapping path="/**/*.jsp"/> <mvc:exclude-mapping path="/**/fonts/*"/> <mvc:exclude-mapping path="/**/*.css"/> <mvc:exclude-mapping path="/**/*.js"/> <mvc:exclude-mapping path="/**/*.png"/> <mvc:exclude-mapping path="/**/*.gif"/> <mvc:exclude-mapping path="/**/*.jpg"/> <mvc:exclude-mapping path="/**/*.jpeg"/> <bean class="com.AccessInterceptor"></bean> </mvc:interceptor> </mvc:interceptors>
-
拦截器实现类AccessInterceptor。在preHandle 对拦截到的请求进行处理,如果sesssion过期,就跳转。
public class AccessInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // TODO Auto-generated method stub //System.out.println("[AccessInterceptor]:preHandle执行"); //System.out.println("uri:"+request.getRequestURI()); HttpSession session = request.getSession(); // ServletContext application = session.getServletContext(); Object attribute = session.getAttribute("CURRENT_USER"); if( attribute== null){ //未登录 redirect(request,response); return false; }else{ //已经登录 return true; } } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // TODO Auto-generated method stub } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // TODO Auto-generated method stub } //对于请求是ajax请求重定向问题的处理方法 public void redirect(HttpServletRequest request, HttpServletResponse response) throws IOException{ //获取当前请求的路径 String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()+request.getContextPath(); //如果request.getHeader("X-Requested-With") 返回的是"XMLHttpRequest"说明就是ajax请求,需要特殊处理 否则直接重定向就可以了 if("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))){ //告诉ajax我是重定向 response.setHeader("REDIRECT", "REDIRECT"); //告诉ajax我重定向的路径 response.setHeader("CONTENTPATH", basePath+"/login/login.html"); response.setStatus(HttpServletResponse.SC_FORBIDDEN); }else{ response.sendRedirect(basePath + "/loginP13.html"); } }
-
跳转问题分两种,ajax跳转,非ajax跳转。由于ajax 是局部刷新,因此不能在后台进行跳转,需要在请求的js中跳转,可以在ajaxSetup()方法中统一处理,即在请求完成后定义相关跳转操作。非ajax跳转使用response.sendRedirect() 直接跳转即可。
$.ajaxSetup({ complete : function(xhr, status) { //拦截器实现超时跳转到登录页面 // 通过xhr取得响应头 var REDIRECT = xhr.getResponseHeader("REDIRECT"); //如果响应头中包含 REDIRECT 则说明是拦截器返回的 if (REDIRECT == "REDIRECT") { var win = window; while (win != win.top) { win = win.top; } //重新跳转到 login.html win.location.href = xhr.getResponseHeader("CONTEXTPATH"); } } });