SpringBoot(11) SpringBoot自定義攔截器
自定義攔截器共兩步:第一:註冊。第二:定義攔截器。
一、註冊 @Configuration
繼承WebMvcConfigurationAdapter(SpringBoot2.X之前舊版本)
舊版本程式碼
1 @Configuration 2 public class CustomOldWebMvcConfigurer extends WebMvcConfigurerAdapter { 3 4 @Override 5 public void addInterceptors(InterceptorRegistry registry) { 6 7registry.addInterceptor(new LoginIntercepter()).addPathPatterns("/api/"); 8 9 super.addInterceptors(registry); 10 } 11 12 }
SpringBoot2.X 新版本配置攔截器 implements WebMvcConfigurer
新版本程式碼
1 @Configuration 2 public class CustomWebMvcConfigurer implements WebMvcConfigurer {3 4 @Override 5 public void addInterceptors(InterceptorRegistry registry) { 6 7 registry.addInterceptor(new LoginIntercepter()).addPathPatterns("/api2/*/**").excludePathPatterns("/api2/xxx/**");; 8 registry.addInterceptor(new TwoIntercepter()).addPathPatterns("/api2/*/**"); 9WebMvcConfigurer.super.addInterceptors(registry); 10 } 11 12 }
二、定義攔截器 HandlerInterceptor
1、LoginIntercepter
1 public class LoginIntercepter implements HandlerInterceptor{ 2 3 /** 4 * 進入controller方法之前 5 */ 6 @Override 7 public boolean preHandle(HttpServletRequest request, 8 HttpServletResponse response, Object handler) throws Exception { 9 System.out.println("LoginIntercepter------->preHandle"); 10 11 // String token = request.getParameter("access_token"); 12 // 13 // response.getWriter().print("fail"); 14 // return true; 15 return HandlerInterceptor.super.preHandle(request, response, handler); 16 } 17 18 /** 19 * 呼叫完controller之後,檢視渲染之前 20 */ 21 @Override 22 public void postHandle(HttpServletRequest request, 23 HttpServletResponse response, Object handler, 24 ModelAndView modelAndView) throws Exception { 25 26 System.out.println("LoginIntercepter------->postHandle"); 27 28 HandlerInterceptor.super.postHandle(request, response, handler, modelAndView); 29 } 30 31 /** 32 * 整個完成之後,通常用於資源清理 33 */ 34 @Override 35 public void afterCompletion(HttpServletRequest request, 36 HttpServletResponse response, Object handler, Exception ex) 37 throws Exception { 38 System.out.println("LoginIntercepter------->afterCompletion"); 39 40 HandlerInterceptor.super.afterCompletion(request, response, handler, ex); 41 } 42 43 }
2、TwoIntercepter
1 public class TwoIntercepter implements HandlerInterceptor{ 2 3 /** 4 * 進入對應的controller方法之前 5 */ 6 @Override 7 public boolean preHandle(HttpServletRequest request, 8 HttpServletResponse response, Object handler) throws Exception { 9 10 System.out.println("TwoIntercepter------>preHandle"); 11 12 //return true; 13 return HandlerInterceptor.super.preHandle(request, response, handler); 14 } 15 16 /** 17 * controller處理之後,返回對應的檢視之前 18 */ 19 @Override 20 public void postHandle(HttpServletRequest request, 21 HttpServletResponse response, Object handler, 22 ModelAndView modelAndView) throws Exception { 23 System.out.println("TwoIntercepter------>postHandle"); 24 HandlerInterceptor.super.postHandle(request, response, handler, modelAndView); 25 } 26 27 /** 28 * 整個請求結束後呼叫,檢視渲染後,主要用於資源的清理 29 */ 30 @Override 31 public void afterCompletion(HttpServletRequest request, 32 HttpServletResponse response, Object handler, Exception ex) 33 throws Exception { 34 System.out.println("TwoIntercepter------>afterCompletion"); 35 HandlerInterceptor.super.afterCompletion(request, response, handler, ex); 36 } 37 38 39 }
注:
1. 三個過載方法說明
preHandle:呼叫Controller某個方法之前
postHandle:Controller之後呼叫,檢視渲染之前,如果控制器Controller出現了異常,則不會執行此方法
afterCompletion:不管有沒有異常,這個afterCompletion都會被呼叫,用於資源清理
2.順序
按照註冊順序進行攔截,先註冊,先被攔截
三、攔截器不生效常見問題:
1)是否有加@Configuration
2)攔截路徑是否有問題 ** 和 *
3)攔截器最後路徑一定要 “/**”, 如果是目錄的話則是 /*/
四、過濾器與攔截器的區別
Filter是基於函式回撥 doFilter(),而Interceptor則是基於AOP思想
Filter在只在Servlet前後起作用,而Interceptor夠深入到方法前後、異常丟擲前後等
依賴於Servlet容器即web應用中,而Interceptor不依賴於Servlet容器所以可以執行在多種環境。
在介面呼叫的生命週期裡,Interceptor可以被多次呼叫,而Filter只能在容器初始化時呼叫一次。
Filter和Interceptor的執行順序:過濾前->攔截前->action執行->攔截後->過濾後