学识尚浅,若有需更正地方,请见谅并留言,谢谢!
我们先了解一下一些必要的信息。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;
}