拦截器:Interceptor

1,定义拦截器类:实现HandlerInterceptor接口;

  • 重写三个方法:

    1. preHandle;前置通知
    2. postHandle;
    3. afterCompletion;

      1. public class BookInterceptor implements HandlerInterceptor { //定义拦截器类,实现HandlerInterceptor接口
      2. @Override
      3. //原始方法调用前执行的内容
      4. //返回值类型可以拦截控制的执行,true放行,false终止
      5. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
      6. System.out.println("前置通知");
      7. return true;
      8. }
      9. @Override
      10. //原始方法调用后执行的内容
      11. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
      12. System.out.println("后置通知");
      13. }
      14. @Override
      15. //原始方法调用完成后执行的内容
      16. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
      17. System.out.println("最终通知");
      18. }
      19. }

      1.1,postHandle()和afterCompletion()方法的区别:

      1.1.1,postHandle():后置处理:

      1. //原始方法调用后执行的内容
      2. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
      3. System.out.println("postHandle...");
      4. }

      注意:如果处理器方法出现异常了,该方法不会执行

      1.1.2,afterComplettion():最终处理:

      1. //原始方法调用完成后执行的内容
      2. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
      3. System.out.println("afterCompletion...");
      4. }

      注意:无论处理器方法内部是否出现异常,该方法都会执行。


2,配置加载拦截器:

2.1,方式一:继承WebMvcConfigurationSupport类

注:@Configuration注解已经包含@Component的功能

  1. 在上面添加静态资源的配置类中重写addInterceptors方法
  2. 添加拦截器和多个拦截路径:/book和/book/**
  3. 要注入拦截器对象

    1. @Configuration
    2. public class SpringMvcSupport extends WebMvcConfigurationSupport {
    3. @Override
    4. protected void addInterceptors(InterceptorRegistry registry) {
    5. //注解拦截器和拦截地址
    6. registry.addInterceptor(new BookInterceptor()).addPathPatterns("/book/*");
    7. }
    8. }

    2.2,方式二:实现WebMvcConfigurer接口:

    使用标准接口WebMvcConfigurer简化开发(注意:侵入式较强)

  4. 在SpringMvcConfig主配置类上实现WebMvcConfigurer接口,接口中全是默认方法

  5. 注入拦截器对象,重写addInterceptors方法

注:与方式一两者只能选一种,不然会有冲突,如果方式一起作用会导致第二种方式的拦截器不起使用。
即:如果项目中出现了一次 extends WebMvcConfigurationSupport ,其他的 extends WebMvcConfigurationSupport 和 implements WebMvcConfigurer 会失效 。

  1. @Configuration
  2. //同时扫描控制器和配置类所在的包
  3. @ComponentScan({"com.itheima.controller","com.itheima.config"})
  4. @EnableWebMvc
  5. public class SpringMvcConfig implements WebMvcConfigurer {
  6. @Override
  7. public void addInterceptors(InterceptorRegistry registry) {
  8. registry.addInterceptor(new BookInterceptor()).addPathPatterns("/book/*");
  9. }
  10. }

image.png
拦截器链的前置顺序:pre1-3;
当pre3返回FALSE:那直到after2才执行;(post 3-1,全跳过,而after3是属于pre3的,因此也不执行,而after2-1 pre3管不着,因此正常执行;
pre2 同理;直到after1才执行