现在的位置: 首页 > 综合 > 正文

session超时处理

2017年12月27日 ⁄ 综合 ⁄ 共 3557字 ⁄ 字号 评论关闭

---需求(摘自网络):
1."在一次做非常复杂的ajax应用时,如果一个会话已经超时,但是此时再通过ajax请求,那么ajax返回的则是一个登陆页面的html,那这下就惨了,页面上而已就乱了"
2."对于普通的http请求,可以通过过滤器Filter来判断session超时,然后跳转到登录页面;但是对于Ajax请求,则不会如期待的那样自动转到登录页面(我试了网站上的许多种方案,都是停留在当前页面)"
3.Ajax请求后台数据虽然会被过滤器filter拦截,但是因为Ajax操作与对页面整个页面的提交请求不一样,filter中的重定向并不能使之跳到一个新的页面,因此需要我们去做特殊的处理。处理原理很简单,如果session超时,filter返回一个超时标识给客户端,客户端检测到超时头信息,跳转到指定页面。
4.当session超时时,如果不是ajax请求,很简单就能实现跳到指定的页面;但是ajax请求就会有问题:如果是ajax类型的弹出框则会在弹出框中显示跳转的指定页面,如果是正常ajax请求,则可能会显示源代码等。
5.http://www.iteye.com/topic/1126552
6.http://www.cnblogs.com/shencheng/archive/2011/01/07/1930227.html
7.区分ajax请求和普通http请求:session超时处理、exception处理

---sessionListener

web.xml:

    <session-config> 
       <session-timeout>1</session-timeout> <!--单位min,若为-1则永远不超时-->
    </session-config> 
    
    <listener>
       <listener-class>test.MyHttpSessionListener</listener-class>
    </listener>

Listener:

	public class MyHttpSessionListener implements HttpSessionListener {  
		//创建  
		public void sessionCreated(HttpSessionEvent arg0) {  
			System.out.println("sessionCreated..........");  
		}  
		//销毁
		public void sessionDestroyed(HttpSessionEvent arg0) {  
			System.out.println("sessionDestroyed........");  
		}  
	} 

---session过期判断:跳转到登录页面
web.xml:(配置在springmvc的拦截之前)

  <filter>
      <filter-name>sessionFilter</filter-name>
      <filter-class>test.SessionFilter</filter-class> 
  </filter>
  <filter-mapping>
      <filter-name>sessionFilter</filter-name>
      <url-pattern>/user/*</url-pattern>
  </filter-mapping>

Filter:

public class SessionFilter implements Filter {
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
			ServletException {
		if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) {
			throw new ServletException("OncePerRequestFilter just supports HTTP requests");
		}		 
		HttpServletRequest req = (HttpServletRequest) request;
		HttpServletResponse res = (HttpServletResponse) response;
		
//		String userId = (String) req.getSession().getAttribute("userId");
//		if ((userId == null) || "".equals(userId)) {
//			res.sendRedirect(req.getContextPath() + "/loginDemo");
//		}
		System.out.println("判断: " + req.getSession(false));
		if (null == req.getSession(false)) {
//			if (true == req.getSession(true).isNew()) {
//				System.out.println("new request");
//			} 
			System.out.println("session已经过期");
			if (req.getHeader("x-requested-with") != null 
					&& req.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")) {  
				System.out.println("ajax超时处理..............");
				res.addHeader("sessionstatus", "timeout");   
				res.addHeader("loginPath","loginurl");
				
				res.setCharacterEncoding("utf-8");
	            res.setContentType("text/html;charset=UTF-8");
	            OutputStream out = response.getOutputStream();
	            PrintWriter pw = new PrintWriter(new OutputStreamWriter(out,"utf-8"));
	            pw.println("{\"result\":false,\"errorMessage\":\"您未登录,请先登录\"}");
	            pw.flush();
	            pw.close();
				//前端js处理
	            return;
			}else{
				System.out.println("http超时处理.............");
				res.sendRedirect(req.getContextPath() + "/index.page");
				return;
			} 
		} else{
			System.out.println("Session is active!");
		}
		
		System.out.println("sessionFilter doFilter..........");
		chain.doFilter(request, response);
	}

	public void destroy() {
	}

	public void init(FilterConfig filterConfig) {
	}
}

--前端JS处理:

	$(document).ajaxComplete(function(event, xhr, settings) {
		if(xhr.getResponseHeader("sessionstatus")=="timeOut"){
			if(xhr.getResponseHeader("loginPath")){
				window.location.replace(xhr.getResponseHeader("loginPath"));
			}else{
				alert("Request time out relogin plase !");
			}
		}
	}); 


	//全局的ajax访问,处理ajax清求时sesion超时
	$.ajaxSetup({
		contentType:"application/x-www-form-urlencoded;charset=utf-8",
		complete:function(XMLHttpRequest,textStatus){
			//通过XMLHttpRequest取得响应头,sessionstatus,
			var sessionstatus=XMLHttpRequest.getResponseHeader("sessionstatus"); 
			if(sessionstatus=="timeout"){
			//如果超时就处理 ,指定要跳转的页面
				window.location = "<c:url value="/" />";
			}
		}
	});

抱歉!评论已关闭.