Spring Boot 2.X(九):Spring MVC - 拦截器(Interceptor)

简介: 拦截器 1.简介 Spring MVC 中的拦截器(Interceptor)类似与 Servlet 开发中的过滤器 Filter,它主要用于拦截用户请求并作相应的处理,它也是 AOP 编程思想的体现,底层通过动态代理模式完成。

拦截器

1.简介

Spring MVC 中的拦截器(Interceptor)类似与 Servlet 开发中的过滤器 Filter,它主要用于拦截用户请求并作相应的处理,它也是 AOP 编程思想的体现,底层通过动态代理模式完成。

2.定义实现类

拦截器有两种实现方式:
1.实现 HandlerInterceptor 接口
2.继承 HandlerInterceptorAdapter 抽象类(看源码最底层也是通过 HandlerInterceptor 接口 实现)

3.HandlerInterceptor方法介绍

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        
        //进行逻辑判断,如果ok就返回true,不行就返回false,返回false就不会处理请求
        return true;
    }
    
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
    }

preHandle:在业务处理器处理请求之前被调用。预处理,可以进行编码、安全控制、权限校验等处理;
postHandle:在业务处理器处理请求执行完成后,生成视图之前执行。
afterCompletion:在 DispatcherServlet 完全处理完请求后被调用,可用于清理资源等。

4.应用场景

1.日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算PV(Page View)等;
2.登录鉴权:如登录检测,进入处理器检测检测是否登录;

3.性能监控:检测方法的执行时间;
4.其他通用行为。

5.与 Filter 过滤器的区别

1.拦截器是基于java的反射机制的,而过滤器是基于函数回调。

2.拦截器不依赖于servlet容器,而过滤器依赖于servlet容器。
3.拦截器只能对Controller请求起作用,而过滤器则可以对几乎所有的请求起作用。
4.拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
5.在Controller的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
6.拦截器可以获取IOC容器中的各个bean,而过滤器不行。这点很重要,在拦截器里注入一个service,可以调用业务逻辑。

具体实现

单个拦截器

1.新建拦截器

    public class Test1Interceptor implements HandlerInterceptor{

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println("执行preHandle方法-->01");
        return true;
    }
    
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println("执行postHandle方法-->02");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println("执行afterCompletion方法-->03");
    }
}

2.配置拦截器

@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
    /*
     * 拦截器配置
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册自定义拦截器,添加拦截路径和排除拦截路径
        registry.addInterceptor(new Test1Interceptor()) // 添加拦截器
                .addPathPatterns("/**") // 添加拦截路径
                .excludePathPatterns(// 添加排除拦截路径
                        "/hello").order(0);//执行顺序
        super.addInterceptors(registry);
    }

}

3.测试拦截器

@RestController
public class TestController {

    @RequestMapping("/hello")
    public String getHello() {
        System.out.println("这里是Hello");
        return "hello world";
    }
    
    
    @RequestMapping("/test1")
    public String getTest1() {
        System.out.println("这里是Test1");
        return "test1 content";
    }
    
    @RequestMapping("/test2")
    public String getTest2() {
        System.out.println("这里是Test2");
        return "test2 content";
    }
}

4.单个拦截器的执行流程

通过浏览器测试:
http://127.0.0.1:8080/hello
结果:

这里是Hello

http://127.0.0.1:8080/test1http://127.0.0.1:8080/test2
结果:

执行preHandle方法-->01
这里是Test1
执行postHandle方法-->02
执行afterCompletion方法-->03

多个拦截器

1.新建两个拦截器

Test1Interceptor

public class Test1Interceptor implements HandlerInterceptor{
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println("执行Test1Interceptor preHandle方法-->01");
        return true;
    }
    
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println("执行Test1Interceptor postHandle方法-->02");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println("执行Test1Interceptor afterCompletion方法-->03");
    }
}

Test2Interceptor

public class Test2Interceptor extends HandlerInterceptorAdapter{


    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println("执行Test2Interceptor preHandle方法-->01");
        return true;
    }
    
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println("执行Test2Interceptor postHandle方法-->02");
    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println("执行Test2Interceptor afterCompletion方法-->03");
    }
}

2.配置拦截器

@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
    /*
     * 拦截器配置
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册自定义拦截器,添加拦截路径和排除拦截路径
        registry.addInterceptor(new Test1Interceptor()) // 添加拦截器1
                .addPathPatterns("/**") // 添加拦截路径
                .excludePathPatterns(// 添加排除拦截路径
                        "/hello")
                .order(0);
        registry.addInterceptor(new Test2Interceptor()) // 添加拦截器2
                .addPathPatterns("/**") // 添加拦截路径
                .excludePathPatterns(// 添加排除拦截路径
                        "/test1")
                .order(1);
        super.addInterceptors(registry);
    }

}

3.测试拦截器

@RestController
public class TestController {

    @RequestMapping("/hello")
    public String getHello() {
        System.out.println("这里是Hello");
        return "hello world";
    }
    
    
    @RequestMapping("/test1")
    public String getTest1() {
        System.out.println("这里是Test1");
        return "test1 content";
    }
    
    @RequestMapping("/test2")
    public String getTest2() {
        System.out.println("这里是Test2");
        return "test2 content";
    }
}

4.多个拦截器的执行流程

通过浏览器测试:
http://127.0.0.1:8080/test2
结果:

执行Test1Interceptor preHandle方法-->01
执行Test2Interceptor preHandle方法-->01
这里是Test2
执行Test2Interceptor postHandle方法-->02
执行Test1Interceptor postHandle方法-->02
执行Test2Interceptor afterCompletion方法-->03
执行Test1Interceptor afterCompletion方法-->03

通过示例,简单的说多个拦截器执行流程就是先进后出

简单的 token 判断示例

1.拦截器

@Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println("执行Test1Interceptor preHandle方法-->01");
        
        String token = request.getParameter("token");
        if (StringUtils.isEmpty(token)) {            
            response.setContentType("text/html");
            response.setCharacterEncoding("UTF-8");
            response.getWriter().println("token不存在");
            return false;
        }
        return true;
    }

2.测试及结果

未传token:

执行Test1Interceptor preHandle方法-->01

传token:

执行Test1Interceptor preHandle方法-->01
页码:1
页码大小:10
执行Test1Interceptor postHandle方法-->02
执行Test1Interceptor afterCompletion方法-->03

示例代码

github

码云

非特殊说明,本文版权归 朝雾轻寒 所有,转载请注明出处.

原文标题:Spring Boot 2.X(九):Spring MVC - 拦截器(Interceptor)

原文地址: https://www.zwqh.top/article/info/18

如果文章对您有帮助,请扫码关注下我的公众号,文章持续更新中...

相关文章
|
23天前
|
设计模式 前端开发 Java
步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理
通过对 `DispatcherServlet`源码的深入剖析,我们了解了SpringMVC请求处理的全流程。`DispatcherServlet`作为前端控制器,负责请求的接收和分发,处理器映射和适配负责将请求分派到具体的处理器方法,视图解析器负责生成和渲染视图。理解这些核心组件及其交互原理,有助于开发者更好地使用和扩展SpringMVC框架。
38 4
|
2月前
|
监控 Java 数据安全/隐私保护
如何用Spring Boot实现拦截器:从入门到实践
如何用Spring Boot实现拦截器:从入门到实践
57 5
|
2月前
|
前端开发 Java 开发者
Spring MVC中的请求映射:@RequestMapping注解深度解析
在Spring MVC框架中,`@RequestMapping`注解是实现请求映射的关键,它将HTTP请求映射到相应的处理器方法上。本文将深入探讨`@RequestMapping`注解的工作原理、使用方法以及最佳实践,为开发者提供一份详尽的技术干货。
154 2
|
3月前
|
JSON 前端开发 Java
SSM:SpringMVC
本文介绍了SpringMVC的依赖配置、请求参数处理、注解开发、JSON处理、拦截器、文件上传下载以及相关注意事项。首先,需要在`pom.xml`中添加必要的依赖,包括Servlet、JSTL、Spring Web MVC等。接着,在`web.xml`中配置DispatcherServlet,并设置Spring MVC的相关配置,如组件扫描、默认Servlet处理器等。然后,通过`@RequestMapping`等注解处理请求参数,使用`@ResponseBody`返回JSON数据。此外,还介绍了如何创建和配置拦截器、文件上传下载的功能,并强调了JSP文件的放置位置,避免404错误。
|
3月前
|
Java API Spring
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
这篇文章是关于Spring Boot 2.x中拦截器的入门教程和实战项目场景实现的详细指南。
43 0
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
|
3月前
|
前端开发 Java 应用服务中间件
【Spring】Spring MVC的项目准备和连接建立
【Spring】Spring MVC的项目准备和连接建立
68 2
|
3月前
|
XML 前端开发 Java
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习
本文阐述了Spring、Spring Boot和Spring MVC的关系与区别,指出Spring是一个轻量级、一站式、模块化的应用程序开发框架,Spring MVC是Spring的一个子框架,专注于Web应用和网络接口开发,而Spring Boot则是对Spring的封装,用于简化Spring应用的开发。
239 0
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习
|
3月前
|
存储 JSON 算法
JWT令牌基础教程 全方位带你剖析JWT令牌,在Springboot中使用JWT技术体系,完成拦截器的实现 Interceptor (后附源码)
文章介绍了JWT令牌的基础教程,包括其应用场景、组成部分、生成和校验方法,并在Springboot中使用JWT技术体系完成拦截器的实现。
171 0
JWT令牌基础教程 全方位带你剖析JWT令牌,在Springboot中使用JWT技术体系,完成拦截器的实现 Interceptor (后附源码)
|
4月前
|
XML 缓存 前端开发
springMVC02,restful风格,请求转发和重定向
文章介绍了RESTful风格的基本概念和特点,并展示了如何使用SpringMVC实现RESTful风格的请求处理。同时,文章还讨论了SpringMVC中的请求转发和重定向的实现方式,并通过具体代码示例进行了说明。
springMVC02,restful风格,请求转发和重定向
|
5月前
|
开发框架 前端开发 .NET
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
70 0
下一篇
开通oss服务