您好,登錄后才能下訂單哦!
SpringMVC 配置攔截器
1. 作為攔截器當然是為了攔截 (這不是廢話嘛) 那攔截是為了干嘛?
它可以幫我們攔截未登錄用戶 驗證是否登錄、設置日志記錄、統計一些接口訪問量啊
進行統一異常處理 設置一些數據啊 或者計算下應用接口方法執行效率啊 等等
2. 配置攔截器
由于用的是SpringMVC所以要知道 它是有個統一的 DispatcherServlet 控制器,
所以就不用傳統的bean方式了,人家給我們提供了其他簡單的方式
如下所示: (我設置了三個方便測試用的)
<!--攔截器 -->
<mvc:interceptors>
<!--多個攔截器,順序執行 -->
<mvc:interceptor>
<mvc:mapping path="/**" />
<!-- 表示攔截所有的url,包括子url路徑 -->
<bean class="com.tz.interceptor.LoginHandlerInterceptor"></bean>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="com.tz.interceptor.LoginHandlerInterceptor2"></bean>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="com.tz.interceptor.LoginHandlerInterceptor3"></bean>
</mvc:interceptor>
</mvc:interceptors>
SpringMVC 攔截器需要實現 HandlerInterceptor 接口,它有三個方法:
(1) preHandle方法
該方法將在Controller處理之前進行調用,SpringMVC中的Interceptor攔截器是鏈式的,
可以同時存在,多個Interceptor,然后SpringMVC會根據聲明的前后順序一個接一個的
執行,而且所有的Interceptor中的preHandle方法都會在 Controller方法調用之前調用。
SpringMVC的這種Interceptor鏈式結構也是可以進行中斷的,這種中斷方式是令 preHandle的返回值為false,當preHandle的返回值為false的時候整個請求就結束了。
(2) postHandle 方法
這個方法只會在當前這個Interceptor的preHandle方法返回值為true的時候才會執行。
postHandle是進行處理器攔截用的,它的執行時間是在處理器進行處理之后,
也就是在Controller的方法調用之后執行,但是它會在DispatcherServlet進行視圖的
渲染之前執行,也就是說在這個方法中你可以對ModelAndView進行操作,
這個方法的鏈式結構跟正常訪問的方向是相反的,
也就是說先聲明的Interceptor攔截器該方法反而會后調用,(這句話等下你就會明白了)
這跟Struts2里面的攔截器的執行過程有點像,
只是Struts2里面的intercept方法中要手動的調用ActionInvocation的invoke方法
Struts2中調用ActionInvocation的invoke方法就是調用下一個Interceptor
或者是調用action,然后要在Interceptor之前調用的內容都寫在調用invoke之前,
要在Interceptor之后調用的內容都寫在調用invoke方法之后
(3) afterCompletion方法
請求完成后調用,這時把你要做什么事寫上去,比如 清理資源
那么建立的攔截器類: 其他兩個都一樣
public class LoginHandlerInterceptor implements HandlerInterceptor {
/***
* 請求傳送到接口之前調用該方法,如true通過則進入接口請求數據
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("LoginHandlerInterceptor ------ preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {
System.out.println("LoginHandlerInterceptor ------ postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("LoginHandlerInterceptor ------ afterCompletion");
}
}
3.那么多個攔截器的執行過程又是如何的?
第二個攔截器不通過的 結果:
LoginHandlerInterceptor ----------preHandle
LoginHandlerInterceptor2 ------ preHandle
LoginHandlerInterceptor ----------afterCompletion
也就是說第二個攔截器不會執行他自己之后的兩個方法和postHandle() 方法 ,以及之后的攔截器
第三個攔截器不通過的 結果:
LoginHandlerInterceptor ----------preHandle
LoginHandlerInterceptor2 ------ preHandle
LoginHandlerInterceptor3 ------------ preHandle
LoginHandlerInterceptor2 ------ afterCompletion
LoginHandlerInterceptor ----------afterCompletion
也就是說第三個攔截器不會執行他自己之后的兩個方法和postHandle() 方法 ,以及之后的攔截器
當3個攔截器都通過執行時:
LoginHandlerInterceptor ----------preHandle
LoginHandlerInterceptor2 ------ preHandle
LoginHandlerInterceptor3 ------------ preHandle
LoginHandlerInterceptor3 ---------- postHandle
LoginHandlerInterceptor2 ------ postHandle
LoginHandlerInterceptor ---------- postHandle
LoginHandlerInterceptor3 ---------- afterCompletion
LoginHandlerInterceptor2 ------ afterCompletion
LoginHandlerInterceptor ---------- afterCompletion
總結下:
所以是執行通過了所有的PreHandle()方法之后 才會執行 postHandle() 方法;
preHandle() 方法如果通過了 則執行下一個preHandle(), 不通過則不執行;
然后執行 通過 preHandle() 方法的攔截器的 afterCompletion() 方法
我隨性寫了個登錄攔截器 大神勿噴
public class LoginHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
//獲取請求的url
String url = request.getRequestURI();
System.out.println("LoginHandlerInterceptor ----------preHandle");
//判斷url是否是公開地址,實際使用時應該將公開地址配置在配置文件中,這里公開地址是登錄提交的地址
if(url.indexOf("login") >= 0){
//如果是登錄提交,則放行
return true;
}
HttpSession session = request.getSession();
//從session中取出用于身份信息
String username = (String) session.getAttribute("tzUserName");
if(username != null){
//身份信息驗證通過,放行
return true;
}
//沒有校驗通過,表示用戶身份需要認證,此時需要跳轉到登錄頁面
request.getRequestDispatcher("/views/login.jsp").forward(request, response);
//返回false表示攔截,不向下執行
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("LoginHandlerInterceptor ----------postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("LoginHandlerInterceptor ----------afterCompletion");
}
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。