拦截器拦截请求可以分ajax请求/非ajax请求.
ajax请求在用户session过期之后,需要跳转到登录页面.
这个时候就需要在拦截器里判断我们的请求是否是ajax请求.
但是不能直接的跳转页面,只能通用response返回响应.
我们有两种方式:
1.在ajax里获取响应信息作出执行请求或者session过期跳转到登录页面的操作.
2.修改jQuery源码,这个是比较推荐的做法,要是每次的ajax请求都判断一次,就太扯淡了,比较麻烦,所以就修改源码吧.
1.配置拦截器,list里配置需要放行的请求URL
spring-mvc.xml
<!-- 登录拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<!-- 需要排除拦截的请求 -->
<bean id="LoginInterceptor" class="com.ys.interceptors.LoginInterceptor">
<property name="interceptorList">
<list>
<value>/user/checkLogin</value>
<value>/user/login.html</value>
</list>
</property>
</bean>
</mvc:interceptor>
</mvc:interceptors>
2.编写登录拦截器实现HandlerInterceptor
package com.ys.interceptors;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.ys.entity.User;
import com.ys.listeners.UserSessionListener;
/**
*@Title LoginInterceptor.java
*@description: 登录拦截
*@author lihaichao
*@time 创建时间:2018年5月22日 上午11:49:37
**/
public class LoginInterceptor implements HandlerInterceptor{
private static final Logger logger = Logger.getLogger(LoginInterceptor.class);
/**
* 获取拦截器放行路径
*/
private List<String> interceptorList;
public List<String> getInterceptorList() {
return interceptorList;
}
public void setInterceptorList(List<String> interceptorList) {
this.interceptorList = interceptorList;
}
/**
* 该方法将在请求处理之前进行调用 判断URL是否放行
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
String requestName = request.getServletPath();
logger.debug("拦截器启动 拦截路径为 :"+requestName);
String requestType = request.getHeader("X-Requested-With");
//放行路径 与 请求路径对比 存在则放行
if(interceptorList.contains(requestName)){
return true;
}
User user = (User)request.getSession().getAttribute("user");
if(user != null && UserSessionListener.isContainsKey(user.getId())){
return true;
}else{
if ("XMLHttpRequest".equals(requestType)) {
response.getWriter().write("IsAjax");
} else {
request.getRequestDispatcher("/WEB-INF/view/login/login.jsp").forward(request, response);
}
return false;
}
}
/**
* 该方法将在整个请求结束之前执行
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
logger.debug("处理请求:"+request.getRequestURI());
}
/**
* 该方法将在整个请求结束之后执行
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
logger.debug("请求完成:"+request.getRequestURI());
}
}
在拦截器中添加了是否ajax请求的判断
if ("XMLHttpRequest".equals(requestType)) {
response.getWriter().write("IsAjax");
} else {
request.getRequestDispatcher("/WEB-INF/view/login/login.jsp").forward(request, response);
}
3.接着就是修改jQuery源码,我这里是jquery-2.1.1.min.js
不同版本的jQuery应该差别不大,对比着修改一下就好了.
找到下边的方法
/*function x(a, b, f, h) {
var j, r, s, u, w, x = b;
2 !== t && (t = 2, g && clearTimeout(g), c = void 0, e = h || "", v.readyState = a > 0 ? 4 : 0, j = a >= 200 && 300 > a || 304 === a,
f && (u = uc(k, v, f)), u = vc(k, u, v, j), j ? (k.ifModified && (w = v.getResponseHeader("Last-Modified"),
w && (n.lastModified[d] = w), w = v.getResponseHeader("etag"), w && (n.etag[d] = w)),
204 === a || "HEAD" === k.type ? x = "nocontent": 304 === a ? x = "notmodified": (x = u.state, r = u.data, s = u.error, j = !s)) : (s = x, (a || !x) && (x = "error", 0 > a && (a = 0))), v.status = a, v.statusText = (b || x) + "", j ? o.resolveWith(l, [r, x, v]) : o.rejectWith(l, [v, x, s]), v.statusCode(q), q = void 0, i && m.trigger(j ? "ajaxSuccess": "ajaxError", [v, k, j ? r: s]), p.fireWith(l, [v, x]), i && (m.trigger("ajaxComplete", [v, k]), --n.active || n.event.trigger("ajaxStop")))
}*/
替换为
function x( a, b, f, h ) {
var j, r, s, u, w,x = b;
if ( t === 2 ) { return; }
t = 2;
if ( g ) { clearTimeout( g ); }
c = void 0;
e = h || "";
v.readyState = a > 0 ? 4 : 0;
j = a >= 200 && a < 300 || a === 304;
if ( f ) {
u = uc(k, v, f);
}
u = vc(k, u, v, j);
if ( j ) {
if ( k.ifModified ) {
w = v.getResponseHeader("Last-Modified");
if ( w ) {
n.lastModified[d] = w;
}
w = v.getResponseHeader("etag");
if ( w ) {
n.etag[d] = w;
}
}
if ( 204 === a || "HEAD" === k.type ) {
x = "nocontent";
} else if ( a === 304 ) {
x = "notmodified";
} else {
x = u.state, r = u.data, s = u.error, j = !s
//解决ajax拦截问题
var result = f.text;
if(result.indexOf("IsAjax")>=0){// 拦截登陆
window.parent.location.href=getPath+"user/login.html";
return;
}
}
} else {
s = x;
if ( a || !x ) {
x = "error";
if ( a < 0 ) {
a = 0;
}
}
}
v.status = a;
v.statusText = (b || x) + "";
if ( j ) {
o.resolveWith(l, [r, x, v]);
} else {
o.rejectWith(l, [v, x, s]);
}
// Status-dependent callbacks
v.statusCode( q );
q = void 0;
if ( i ) {
m.trigger( j ? "ajaxSuccess": "ajaxError",
[v, k, j ? r: s]);
}
// Complete
p.fireWith(l, [v, x]);
if ( i ) {
m.trigger("ajaxComplete", [v, k]);
// Handle the global AJAX counter
if ( !( --n.active ) ) {
n.event.trigger("ajaxStop");
}
}
}
主要的地方在这里
if ( 204 === a || "HEAD" === k.type ) {
x = "nocontent";
} else if ( a === 304 ) {
x = "notmodified";
} else {
x = u.state, r = u.data, s = u.error, j = !s
//解决ajax拦截问题
var result = f.text;
if(result.indexOf("IsAjax")>=0){// 拦截登陆
window.parent.location.href=getPath+"user/login.html";
return;
}
}
其中 var result = f.text ; f对应的是responses 获取的就是我们请求的响应数据信息.
在我们的拦截器中 response.getWriter().write(“IsAjax”); 返回了信息.
所以我们直接判断请求响应信息是否有”IsAjax” 就可以了,如果有的话就跳转到登录页面.
在我们请求的时候,如果session过期的话 ,那么ajax就会走error:function(e){alert(e.status);} ,这时获取ajax的请求状态就会是200 . 状态200 代表执行成功 , 用户登录状态都过期了怎么可能会成功呢 .所以让用户重新登录就好了. 这时我们再执行window.parent.location.href = “你的登录页面”; ajax就会在你的session过期而返回状态是200时直接跳转到登录页.
over!
记录错误.