SpringBoot攔截器Interceptor
java裡的攔截器是動態攔截Action呼叫的物件,它提供了一種機制可以使開發者在一個Action執行的前後執行一段程式碼,也可以在一個Action執行前阻止其執行,同時也提供了一種可以提取Action中可重用部分程式碼的方式。在AOP中,攔截器用於在某個方法或者欄位被訪問之前,進行攔截然後再之前或者之後加入某些操作。目前,我們需要掌握的主要是Spring的攔截器,Struts2的攔截器不用深究,知道即可。。
一:攔截器的應用場景
1、日誌記錄:記錄請求資訊的日誌,以便進行資訊監控、資訊統計、計算PV(Page VIEW)等。 2、許可權檢查:如登入檢測,進入處理器檢測檢測是否登入,如果沒有直接返回到登入頁面; 3、效能監控:有時候系統在某段時間莫名其妙的慢,可以通過攔截器在進入處理器之前記錄開始時間,在處理完後記錄結束時間,從而得到該請求的處理時間(如果有反向代理,如apache可以自動記錄); 4、通用行為:讀取cookie得到使用者資訊並將使用者物件放入請求,從而方便後續流程使用,還有如提取Locale、Theme資訊等,只要是多個處理器都需要的即可使用攔截器實現。 5、OpenSessionInView:如Hibernate,在進入處理器開啟SESSION,在完成後關閉SESSION。
二:攔截器與過濾器的區別
1、攔截器是基於Java的反射機制的,而過濾器是基於函式回撥。 2、攔截器不依賴與servlet容器,過濾器依賴與servlet容器。 3、攔截器只能對ACTION請求起作用,而過濾器則可以對幾乎所有的請求起作用。 4、攔截器可以訪問ACTION上下文、值棧裡的物件,而過濾器不能訪問。 5、在ACTION的生命週期中,攔截器可以多次被呼叫,而過濾器只能在容器初始化時被呼叫一次。 6、攔截器可以獲取IOC容器中的各個bean,而過濾器就不行,這點很重要,在攔截器裡注入一個service,可以呼叫業務邏輯。
- 定義攔截器
@Component //宣告為springBoot的一個元件,但是並不能起作用,需要在springBoot的配置類中注入 public class TimeInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("TimeInterceptor 進入 Controller 某個方法之前"); System.out.println("Controller Name:"+((HandlerMethod)handler).getBean().getClass().getName()); System.out.println("Controller Method Name:"+((HandlerMethod)handler).getMethod().getName()); request.setAttribute("startTime", new Date().getTime()); /** * boolean 值: 確定了攔截器其餘兩方法是否執行 */ return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("TimeInterceptor 執行 Controller 某個方法時,方法丟擲異常將不進入此方法"); long start = (long) request.getAttribute("startTime"); System.out.println("TimeInterceptor 處理時長為:"+ (new Date().getTime() - start)); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("TimeInterceptor 完成 Controller 某個方法"); long start = (long) request.getAttribute("startTime"); System.out.println("TimeInterceptor 處理時長為:"+ (new Date().getTime() - start)); } }
- 注入攔截器
//spring boot 1.0 -2.0版本 @Configuration public class WebConfig extends WebMvcConfigurerAdapter { @Autowired private TimeInterceptor timeInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(timeInterceptor); } } //spring boot 2.0以上版本 @Configuration public class MyWebMvcConfig implements WebMvcConfigurer { @Bean public MyWebMvcConfig getMyWebMvcConfig(){ MyWebMvcConfig myWebMvcConfig = new MyWebMvcConfig() { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("alogin"); registry.addViewController("/login").setViewName("alogin"); registry.addViewController("/main.html").setViewName("dashboard"); } //註冊攔截器 @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**") .excludePathPatterns("/login","/","/user/login"); } }; return myWebMvcConfig; }