• SpringMVC 拦截器


    1. 拦截器简介

    1.1 拦截器概念和作用

    拦截器(Interceptor)是一种动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方法的执行

    作用:

    1. 在指定的方法调用前后执行预先设定的代码
    2. 阻止原始方法的执行
    3. 总结:增强

    核心原理:利用AOP思想

    1.2 拦截器和过滤器的区别

    首先他们的归属不同:Filter属于Servlet技术,Interceptor属于SpringMVC技术

    其次拦截内容不同:Filter对所有访问进行增强,Interceptor仅针对SpringMVC的访问进行增强

    请求到达的路线顺序图如下所示:
    image-20210805175539717

    记住一点就好:过滤器是过滤Servlet的,拦截器是拦截SpringMVC的

    在这里插入图片描述

    2. 入门案例

    2.1 拦截器代码实现

    Spring MVC中,所有的拦截器都需要实现HandlerInterceptor接口,该接口包含如下三个方法:preHandle()、postHandle()、afterCompletion()。

    【第一步】定义拦截器

    做法:定义一个类,实现HandlerInterceptor接口即可

    注意当前类必须受Spring容器控制,使用@Component告诉spring进行容器管理

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

    【第二步】配置加载拦截器

    @Configuration
    public class SpringMvcSupport extends WebMvcConfigurationSupport {
        @Autowired
        private ProjectInterceptor projectInterceptor;
    
        @Override
        protected void addInterceptors(InterceptorRegistry registry) {
            //配置拦截器
            registry.addInterceptor(projectInterceptor)
                .addPathPatterns("/users","/users/*");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    上面【第二步】步骤也可以使用标准接口WebMvcConfigurer简化开发(注意:侵入式较强),代码如下所示:

    @Configuration
    @ComponentScan({"com.yyl.controller"})
    @EnableWebMvc
    //实现WebMvcConfigurer接口可以简化开发,但具有一定的侵入性
    public class SpringMvcConfig implements WebMvcConfigurer {
        @Autowired
        private ProjectInterceptor projectInterceptor;
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            //配置多拦截器
            registry.addInterceptor(projectInterceptor)
                .addPathPatterns("/users","/users/*");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2.1.1 Spring MVC拦截器的开发步骤总结:

    1. 开发拦截器:实现handlerInterceptor接口,从三个方法中选择合适的方法,实现拦截时要执行的具体业务逻辑。
    2. 注册拦截器:定义配置类,并让它实现WebMvcConfigurer接口,在接口的addInterceptors方法中,注册拦截器,并定义该拦截器匹配哪些请求路径。

    2.2 拦截器流程分析

    方法执行流程如下:
    在这里插入图片描述

    1. 执行preHandle方法,它会返回一个布尔值。如果为false,则结束所有流程,如果为true,则执行下一步。
    2. 执行处理器逻辑,它包含控制器的功能。
    3. 执行postHandle方法。
    4. 执行视图解析和视图渲染。
    5. 执行afterCompletion方法。

    我们将有无拦截器的流程进行对比:

    我们可以发现拦截器很强大,总的来说是可以用来增强处理器功能的
    image-20210805180846313

    3. 拦截器参数

    3.1 前置处理

    在原始方法调用前执行的内容

    //原始方法调用前执行的内容
    //返回值类型可以拦截控制的执行,true放行,false终止
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle..."+contentType);
        return true;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    参数

    参数说明
    request请求对象
    response响应对象
    handler被调用的处理器对象,本质上是一个方法对象,对反射技术中的Method对象进行了再包装

    返回值

    • 返回值为true,放行,继续执行被拦截处理器内容
    • 返回值为false,被拦截的处理器将不执行。

    3.2 后置处理

    在原始方法调用后执行的内容

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

    参数

    参数说明
    request请求对象
    response响应对象
    handler被调用的处理器对象,本质上是一个方法对象,对反射技术中的Method对象进行了再包装
    modelAndView如果处理器执行完成具有返回结果,可以读取到对应数据与页面信息,并进行跳转

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

    3.3 完成后处理

    在原始方法调用完成后执行的内容

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

    参数

    参数说明
    request请求对象
    response响应对象
    handler被调用的处理器对象,本质上是一个方法对象,对反射技术中的Method对象进行了再包装
    ex如果处理器执行过程中出现异常对象,可以针对异常情况进行单独处理

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

    4. 拦截器链配置

    4.1 多个拦截器配置

    • 定义第二个拦截器
    @Component
    public class ProjectInterceptor2 implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("preHandle...222");
            return false;
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            System.out.println("postHandle...222");
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            System.out.println("afterCompletion...222");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 配置第二个拦截器
    @Configuration
    @ComponentScan({"com.itheima.controller"})
    @EnableWebMvc
    //实现WebMvcConfigurer接口可以简化开发,但具有一定的侵入性
    public class SpringMvcConfig implements WebMvcConfigurer {
        @Autowired
        private ProjectInterceptor projectInterceptor;
        @Autowired
        private ProjectInterceptor2 projectInterceptor2;
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            //配置多拦截器
            registry.addInterceptor(projectInterceptor)
                .addPathPatterns("/books","/books/*");
            registry.addInterceptor(projectInterceptor2)
                .addPathPatterns("/books","/books/*");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    4.2 多个连接器工作流程分析

    • 当配置多个拦截器时,形成拦截器链
    • 拦截器链的运行顺序参照拦截器添加顺序为准
    • 当拦截器中出现对原始处理器的拦截,后面的拦截器均终止运行
    • 当拦截器运行中断,仅运行配置在前面的拦截器的afterCompletion操作

    image-20210805181537718

  • 相关阅读:
    计算机竞赛 深度学习 YOLO 实现车牌识别算法
    Swfit获取系统开机时间BootTime
    Swift Combine 使用调试器调试管道 从入门到精通二十六
    MapReduce实战小案例(自定义排序、二次排序、分组、分区)
    GFS分布式文件系统
    如何生成一个足够安全又容易记住的密码?
    从零开始Blazor Server(7)--使用Furion权限验证
    如果线上遇到了OOM,该如何解决?
    vscode新建vue3文件模板
    【English】十大词性之连词
  • 原文地址:https://blog.csdn.net/weixin_45525272/article/details/126072520