1. 程式人生 > >spring-mvc ajax訪問 session超時 新增攔截

spring-mvc ajax訪問 session超時 新增攔截

學識尚淺,若有需更正地方,請見諒並留言,謝謝!

我們先了解一下一些必要的資訊。ajax 請求和普通的 http 請求是不一樣的,Ajax請求是XMLHTTPRequest物件發起的,而http請求是瀏覽器發起的。

二者不同地方體現在HTTP請求的頭資訊中。

AJAX請求頭中帶有X-Requested-With資訊,其值為XMLHttpRequest。而普通請求是沒有的。

spring-mvc.xml 配置檔案設定

<!-- 配置攔截器,攔截請求(除了登入ajax請求外攔截全部ajax請求) -->
    <mvc:interceptors >
	    <mvc:interceptor>
	    	<mvc:mapping path="/**"/>
    		<mvc:exclude-mapping path="/admin/login/**"/>	
    		<bean class="com.wxc.paycoss.filter.AjaxCheckSession"/>
    	</mvc:interceptor>
    </mvc:interceptors></span>

說明:其中<bean> 中的 class 是對應包下的攔截器路徑

下面是攔截器  AjaxCheckSession.java  (這個類自由命名)

package com.wxc.paycoss.filter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.util.UrlPathHelper;

import com.cvicse.paycoss.base.Const;
import com.cvicse.paycoss.domain.Oper;


public class AjaxCheckSession  extends HandlerInterceptorAdapter{
	private final Logger logger = LoggerFactory.getLogger(PaycossContextListener.class);
	 // URL輔助工具類
    private UrlPathHelper urlPathHelper = new UrlPathHelper();

	@Override
	public void afterCompletion(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		// TODO Auto-generated method stub
		super.afterCompletion(request, response, handler, ex);
	}

	@Override
	public void afterConcurrentHandlingStarted(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
		// TODO Auto-generated method stub
		super.afterConcurrentHandlingStarted(request, response, handler);
	}

	@Override
	public void postHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		// TODO Auto-generated method stub
		super.postHandle(request, response, handler, modelAndView);
	}

	@Override
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
		
		
		Oper oper = (Oper) request.getSession().getAttribute(Const.SESSION_LOGIN_ADMIN_USER);
		
		String requestCTX = urlPathHelper.getContextPath(request);
		System.out.println(requestCTX);
	 	String requestUri = request.getRequestURI(); //請求完整路徑,可用於登陸後跳轉
	 	String contextPath = request.getContextPath();  //專案下完整路徑
	 	String url = requestUri.substring(contextPath.length()); //請求頁面
	 	logger.debug("======攔截器配置成功======");
	 	logger.debug("======攔截來自:"+requestUri+"的請求=======");
	 	logger.debug("======攔截的頁面路徑是:==:"+url+"=======");
	 	//throw new Exception("登入超時!");
	 	
 		if(oper == null){//如果獲取不到登入的session
 			//如果是ajax請求
 			if (request.getHeader("x-requested-with") != null 
 					&& request.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")){ 
 				response.setHeader("sessionstatus", "timeout"); // 響應頭設定session狀態 
 				return false;  //session超時,ajax訪問返回false
 			}
 		}
		
		return super.preHandle(request, response, handler);
	}
	
}
以上程式碼有一些log列印根據自己需要,可以只選其中必須的程式碼

有了配置檔案,也有了攔截器,在攔截器中已經設定了返回的資訊,而這些資訊會被 javascript 獲取到。

$.ajaxSetup方法是來設定AJAX請求預設選項的,我們可以認為是全域性的選項設定,因此可以將這段程式碼提到外部JS檔案中,在需要的頁面引用。

/**
 * 設定未來(全域性)的AJAX請求預設選項
 * 主要設定了AJAX請求遇到Session過期的情況
 */

$.ajaxSetup({
  type: 'POST',
  contentType:"application/x-www-form-urlencoded;charset=utf-8",
  complete: function(xhr,status) {
    var sessionStatus = xhr.getResponseHeader('sessionstatus');
    if(sessionStatus == 'timeout') {
      //var top = getTopWinow();
      //var yes = confirm('由於您長時間沒有操作, session已過期, 請重新登入.');
      //if (yes) {
    	alert("登入超時,請重新登入!");
    	window.location.href = '/admin/login/out.do';
      //}
    }
  }
});

/**
* 在頁面中任何巢狀層次的視窗中獲取頂層視窗
* @return 當前頁面的頂層視窗物件
*/

function getTopWinow(){
  var p = window;
  while(p != p.parent){
    p = p.parent;
  }
  return p;
}
在這裡不得不說一下 ajaxSetup 中的 contentType ,若不設定,有可能彈出的資訊是中文,但是往往會出現編碼亂碼。