Spring MVC的處理器攔截器類似於Servlet開發中過濾器Filter,用於對處理器進行預處理和後處理。
其本質也是AOP,也就是說符合橫切關注點的所有功能呢都可以放入攔截器實現。
日常使用場景
1、日誌記錄:記錄請求信息的日誌,以便進行信息監控、信息統計、計算PV(訪問量)
2、權限檢查:如登錄檢測,進入處理器檢測是否登錄,如果沒有直接返回到登錄頁面
3、性能監控:有時候系統在某段時間莫名其妙的慢,可以通過攔截器在進入處理器之前記錄開始時間,在處理完後記錄結束時間,從而得到該請求的處理時間(如果有反向代理,如Apache可以自動記錄)
4、通用欣慰:讀取cookie得到用戶信息並將用戶對象放入請求,從而方便後續流程使用,還有如提取Locale、Theme信息等,只要是多個處理器都需要的即可使用攔截器實現。
5、OpenSessionInView:如Hibernate,在進入處理器時打開Session,在完成後關閉Session
單個interceptor的使用
- applicationContext.xml中的配置
<!--全局的interceptor-->
<mvc:interceptors>
<bean class="com.bamzhy.Interceptor.MyHandlerInterceptor1"></bean>
</mvc:interceptors>
- MyHandlerInterceptor1.java
package com.bamzhy.Interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyHandlerInterceptor1 implements HandlerInterceptor{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
System.out.println("MyHandlerInterceptor1.preHandle()");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
System.out.println("MyHandlerInterceptor1.postHandle()");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
System.out.println("MyHandlerInterceptor1.afterHandle()");
}
}
攔截器之preHandle
- 預處理回調方法:實現處理器的預處理(譬如登錄檢查),第三個參數Object handler爲響應的處理器
- 如果返回true的話表示繼續流程(比如調用下一個攔截器或者處理器)
- 如果返回false(比如登錄檢查失敗),不會繼續調用其他攔截器或者處理器,此時我們需要通過response來產生響應
- 如果是多個interceptor的話(以兩個爲例)
<mvc:interceptors>
<bean class="com.bamzhy.Interceptor.MyHandlerInterceptor1"></bean>
<bean class="com.bamzhy.Interceptor.MyHandlerInterceptor2"></bean>
</mvc:interceptors>
雙方true:
MyHandlerInterceptor1.preHandle()
MyHandlerInterceptor2.preHandle()
MyHandlerInterceptor2.postHandle()
MyHandlerInterceptor1.postHandle()
MyHandlerInterceptor2.afterHandle()雙方false
MyHandlerInterceptor1.preHandle()1true 2false
MyHandlerInterceptor1.preHandle()
MyHandlerInterceptor2.preHandle()
MyHandlerInterceptor1.afterHandle()1false 2true
MyHandlerInterceptor1.preHandle()
可配置Interceptor過濾的 url
<!--全局的interceptors-->
<mvc:interceptors>
<bean class="com.bamzhy.Interceptor.MyHandlerInterceptor1"></bean>
<bean class="com.bamzhy.Interceptor.MyHandlerInterceptor2"></bean>
<!--單個interceptor-->
<mvc:interceptor>
<mvc:mapping path="/user/*"/>
<bean class="com.bamzhy.Interceptor.MyHandlerInterceptor3"></bean>
</mvc:interceptor>
</mvc:interceptors>
結果:
MyHandlerInterceptor1.preHandle()
MyHandlerInterceptor2.preHandle()
MyHandlerInterceptor3.preHandle()
MyHandlerInterceptor3.afterHandle()
MyHandlerInterceptor2.afterHandle()
MyHandlerInterceptor1.afterHandle()
- 注意點:
Spring mvc在執行過程是先根據url去找handler(控制器),如果找到控制器再去根據url選擇interceptor,如果沒有找到url對應的控制器,那麼過濾器不會執行。