我們經常會遇到這些類似的情況,當我們登錄到某個網站之後過一段時間再次刷新頁面,可能會跳轉到登錄頁面讓我們再次登錄;在有的網站我們無法查看某些內容,會提示我們權限不足。其實這些都是後臺首先對我們的請求進行了攔截,然後決定跳轉到哪裏,這裏我來講一下我工作中用到的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");
}
}