自定義攔截器共兩步:第一:注冊。第二:定義攔截器。
一、注冊 @Configuration
繼承WebMvcConfigurationAdapter(SpringBoot2.X之前舊版本)
舊版本代碼
1 @Configuration 2 public class CustomOldWebMvcConfigurer extends WebMvcConfigurerAdapter { 3 4 @Override 5 public void addInterceptors(InterceptorRegistry registry) { 6 7 registry.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/*/**"); 9 WebMvcConfigurer.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執行->攔截后->過濾后