我们经常会遇到这些类似的情况,当我们登录到某个网站之后过一段时间再次刷新页面,可能会跳转到登录页面让我们再次登录;在有的网站我们无法查看某些内容,会提示我们权限不足。其实这些都是后台首先对我们的请求进行了拦截,然后决定跳转到哪里,这里我来讲一下我工作中用到的SpringMVC拦截器的用法。
1 配置XML文件
首先在你的Spring XML文件中添加以下内容
<!-- mvc 拦截器,拦截器被包裹在过滤器中,处理请求顺序是:过滤器 -> 拦截器 -> 控制器 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/user*/**" />
<mvc:mapping path="/role*/**" />
<mvc:mapping path="/menu/**" />
<mvc:mapping path="/sys*/**" />
<mvc:mapping path="/index" />
<mvc:exclude-mapping path="/user/tologin" />
<mvc:exclude-mapping path="/user/login" />
<mvc:exclude-mapping path="/instruction/flashtool_inst" />
<mvc:exclude-mapping path="/romPackage/searchrom" />
<bean class="com.trigl.interceptor.LoginInterceptor">
<property name="sessionKey">
<value>user</value>
</property>
<property name="requestUrlKey">
<value>userKey</value>
</property>
<property name="redirectUrl">
<value>user/tologin</value>
</property>
</bean>
</mvc:interceptor>
</mvc:interceptors>
说明几点:
1、每一个拦截器放在<mvc:interceptor>
标签下面
2、<mvc:mapping>
和<mvc:exclude-mapping>
故名思义,分别指会被拦截的和不会被拦截的请求
3、<bean>
中的类就是具体的自定义的拦截器类
2 拦截器类
然后写具体的拦截器类,注意自定义拦截器类必须实现HandlerInterceptor,这是因为我们要实现这个接口的preHandle方法,这个方法就是拦截器对截获的请求将要进行的操作。
package com.trigl.interceptor;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.log4j.Logger;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.trigl.cache.SessionUtil;
/**
* SpringMVC拦截器,用于验证是否登录、登录超时以及权限
* @author 白鑫
* 2016年7月25日 上午9:56:23
*/
public class LoginInterceptor implements HandlerInterceptor {
private Logger logger = Logger.getLogger(this.getClass());
private static final String[] ignoreUrlArray = { "/index", "/user/login",
"/user/tologin", "/user/logout", "/user/toChangePwd",
"/user/changePwd" };
/**
* 用于拦截的Session key
*/
private String sessionKey;
/**
* 拦截后重定向的url
*/
private String redirectUrl;
/**
* 存入session中用户页面跳转回原访问页面的key
*/
private String requestUrlKey;
/**
* true:拦截后先弹窗再跳转,false:不弹窗提示,直接跳转
*/
private boolean inflag = false;
public void afterCompletion(HttpServletRequest req,
HttpServletResponse resp, Object obj, Exception ex)
throws Exception {
}
public void postHandle(HttpServletRequest req, HttpServletResponse resp,
Object obj, ModelAndView mv) throws Exception {
}
/**
* 拦截器处理的入口方法,对请求的操作就在这里进行
*/
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
logger.info("进入拦截器,请求的url为————" + request.getRequestURL());
if (!isAuthorizedRequest(request)) {//未登录直接跳转
// 将访问url存入session中
putRequestUrl(request);
redirectLoginPage(request, response);
// 如果是ajax请求,直接返回
if (!isHttpRequest(request)) {
return false;
}
} else {
if (SessionUtil.getUserLogin(request).getUserName().equals("admin")) {
return true;
}
// 非管理员判断是否有访问权限
String requestUrl = request.getRequestURI().substring(
request.getRequestURI().indexOf("/", 1));
for (String ignoreUrl : ignoreUrlArray) { // 如果是忽略url直接返回true
if (ignoreUrl.equals(requestUrl)) {
return true;
}
}
}
return false;
}
/**
* 验证是否登录
* @param request
* @return
* @throws IOException
* @throws ServletException
*/
protected boolean isAuthorizedRequest(HttpServletRequest request)
throws IOException, ServletException {
HttpSession session = request.getSession(false);
if (session == null) {
return false;
}
Object sessionObject = session.getAttribute(getSessionKey());
return isValidSessionObject(sessionObject);
}
/**
* 验证存储的session对象是否存在
* @param sessionObject
* @return
*/
protected boolean isValidSessionObject(Object sessionObject) {
return sessionObject != null;
}
/**
* 判断是正常的request还是ajax请求 true:正常请求 false:ajax请求
*
* @param request
* @return
*/
public boolean isHttpRequest(HttpServletRequest request) {
// 如果是ajax请求响应头会有,x-requested-with;
if (request.getHeader("x-requested-with") != null
&& request.getHeader("x-requested-with").equalsIgnoreCase(
"XMLHttpRequest")) {
return false;
} else {
return true;
}
}
public boolean isValidRequest(HttpServletRequest request) {
if (request.getHeader("Referer") != null
&& request.getHeader("Referer").contains(
request.getContextPath())) {
return true;
}
return false;
}
/**
* 未登录用户重定向到登录页面
*
* @param request
* @param response
*/
public void redirectLoginPage(HttpServletRequest request,
HttpServletResponse response) {
try {
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<html><head></head>");
out.println("<body><script>");
out.println("var wnd=this.window;");
out.println("while(1){");
out.println("if(wnd==wnd.parent){");
out.println("break;");
out.println("}else");
out.println("wnd=wnd.parent;");
out.println("}");
out.println("wnd.location.href='"
+ ((HttpServletRequest) request).getContextPath() + "/"
+ redirectUrl + "'");
out.println("</script>");
out.println("</body></html>");
out.flush();
out.close();
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
/**
* 获取重定向url,并将它存入session中
* @param request
* @return
*/
public String putRequestUrl(HttpServletRequest request) {
// 获取请求地址,存入session
String requestUrl = request.getRequestURL().toString();
// 获取request中的参数,将参数拼装
Enumeration<String> e = request.getParameterNames();
int i = 0;
while (e.hasMoreElements()) {
String param = e.nextElement();
if (i == 0) {
requestUrl = requestUrl + "?" + param + "="
+ request.getParameter(param);
} else {
requestUrl = requestUrl + "&" + param + "="
+ request.getParameter(param);
}
i++;
}
request.getSession().setAttribute(requestUrlKey, requestUrl);
return requestUrl;
}
public boolean isInflag() {
return inflag;
}
public void setInflag(boolean inflag) {
this.inflag = inflag;
}
public String getRedirectUrl() {
return redirectUrl;
}
public void setRedirectUrl(String redirectUrl) {
this.redirectUrl = redirectUrl;
}
public String getSessionKey() {
return sessionKey;
}
public void setSessionKey(String sessionKey) {
this.sessionKey = sessionKey;
}
public String getRequestUrlKey() {
return requestUrlKey;
}
public void setRequestUrlKey(String requestUrlKey) {
this.requestUrlKey = requestUrlKey;
}
}
其中的SessionUtil类如下:
package com.trigl.cache;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import com.trigl.entity.User;
/**
* 从request中获取session信息
* @author 白鑫
* @date 2016年7月7日 上午8:09:25
*/
public class SessionUtil {
/**
* 获取登录用户
* @param request
* @return
*/
public static User getUserLogin(HttpServletRequest request){
return (User)request.getSession().getAttribute("user");
}
public static User getUserLogin(HttpSession session){
return (User)session.getAttribute("user");
}
}