自定义拦截器共两步:第一:注册。第二:定义拦截器。
一、注册 @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执行->拦截后->过滤后