【Spring Boot系列】- Spring Boot拦截器

简介: 【Spring Boot系列】- Spring Boot拦截器

一、概述

拦截器(Interceptor)是在面向切面编程中应用的,就是在service或者一个方法前调用一个方法,或者在方法后调用一个方法。是基于JAVA的反射机制。可以根据 URL 对请求进行拦截,主要应用于登陆校验、权限验证、乱码解决、性能监控和异常处理等功能。

二、拦截器(Interceptor)定义步骤

在 Spring Boot 项目中,使用拦截器功能通常需要以下 3 步

  1. 定义拦截器
  2. 注册拦截器
  3. 指定拦截规则(如果是拦截所有,静态资源也会被拦截)

2.1 定义拦截器(Interceptor)

定义拦截器十分的简单,只需要创建一个拦截器类,并实现 HandlerInterceptor 接口,重写以下三个方法:

@Slf4j
@Component
public class MyHandleInterceptor implements HandlerInterceptor {
    /**
     * 目标方法执行前
     * 该方法在控制器处理请求方法前执行,其返回值表示是否中断后续操作
     * 返回 true 表示继续向下执行,返回 false 表示中断后续操作
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Object loginUser = request.getSession().getAttribute("loginUser");
        if (loginUser == null) {
            //未登录,返回登陆页
            request.setAttribute("msg", "您没有权限进行此操作,请先登陆!");
            request.getRequestDispatcher("/index.html").forward(request, response);
            return false;
        } else {
            //放行
            return true;
        }
    }
    /**
     * 目标方法执行后
     * 该方法在控制器处理请求方法调用之后、解析视图之前执行
     * 可以通过此方法对请求域中的模型和视图做进一步修改
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("postHandle执行{}", modelAndView);
    }
    /**
     * 页面渲染后
     * 该方法在视图渲染结束后执行
     * 可以通过此方法实现资源清理、记录日志信息等工作
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("afterCompletion执行异常{}", ex);
    }
}

2.2 注册拦截器(Interceptor)

创建一个实现了 WebMvcConfigurer 接口的配置类(使用了 @Configuration 注解的类),重写 addInterceptors() 方法,并在该方法中调用 registry.addInterceptor() 方法将自定义的拦截器注册到容器中。

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    @Resource
    private LoginInterceptor loginInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //注册自己的拦截器,并设置拦截的请求路径
        //addPathPatterns为拦截此请求路径的请求
        //excludePathPatterns为不拦截此路径的请求
    registry.addInterceptor(MyHandleInterceptor).addPathPatterns("/user/*").excludePathPatterns("/user/login");
    }
}

2.3 拦截器原理

  1. 根据当前请求,找到HandlerExecutionChain【可以处理请求的handler以及handler的所有 拦截器】;
  2. 先来顺序执行 所有拦截器的 preHandle方法;
  1. 如果当前拦截器prehandler返回为true。则执行下一个拦截器的preHandle;
  2. 如果当前拦截器返回为false。直接倒序执行所有已经执行了的拦截器的 afterCompletion;
  1. 如果任何一个拦截器返回false。直接跳出不执行目标方法;
  2. 所有拦截器都返回True。执行目标方法;
  3. 倒序执行所有拦截器的postHandle方法;
  4. 前面的步骤有任何异常都会直接倒序触发 afterCompletion;
  5. 页面成功渲染完成以后,也会倒序触发 afterCompletion;

三、过滤器与拦截器区别

  1. 过滤器和拦截器触发时机不一样,过滤器是在请求进入容器后,但请求进入servlet之前进行预处理的。请求结束返回也是,是在servlet处理完后,返回给前端之前。
  2. 、拦截器可以获取IOC容器中的各个bean,而过滤器就不行,因为拦截器是spring提供并管理的,spring的功能可以被拦截器使用,在拦截器里注入一个service,可以调用业务逻辑。而过滤器是JavaEE标准,只需依赖servlet api ,不需要依赖spring。
  3. 过滤器的实现基于回调函数。而拦截器(代理模式)的实现基于反射。
  4. Filter是依赖于Servlet容器,属于Servlet规范的一部分,而拦截器则是独立存在的,可以在任何情况下使用。
  5. Filter的执行由Servlet容器回调完成,而拦截器通常通过动态代理(反射)的方式来执行。
  6. Filter的生命周期由Servlet容器管理,而拦截器则可以通过IoC容器来管理,因此可以通过注入等方式来获取其他Bean的实例,因此使用会更方便。

四、拦截器的应用

是springmvc提供了一个拦截器的机制,它专门用于拦截controller的路由请求。它的本质是:AOP面向切面的编程,也就是说符合横切关注点的功能都可以考虑使用拦截器实现。比如一些应用场景:

  • 权限检查
    用户登录检查,访问项目的内部接口时,可以通过拦截器检测用户是否登录,如果登录,直接放回用户登录页面;接口的安全校验,使用JWT做权限拦截器校验。
  • 日志记录
    更新推荐用原生的AOP机制会更好一点,粒度会更细,控制起来也更方便,如果你是针对某个接口或者某个请求,或者某个业务针对性的记录日志,其实也可以考虑用拦截器来完成。
  • 性能监控
    记录接口访问过程中的开始时间和结束时间的处理机制。
  • 通用行为
    获取cookie信息,获取用户信息,并将用户信息存放到请求头中,方便后续业务的使用。


目录
相关文章
|
19天前
|
监控 Java 应用服务中间件
spring和springboot的区别
spring和springboot的区别
20 1
|
3天前
|
移动开发 前端开发 NoSQL
ruoyi-nbcio从spring2.7.18升级springboot到3.1.7,java从java8升级到17(二)
ruoyi-nbcio从spring2.7.18升级springboot到3.1.7,java从java8升级到17(二)
41 0
|
4天前
|
XML Java 数据库连接
Spring框架与Spring Boot的区别和联系
Spring框架与Spring Boot的区别和联系
13 0
|
14天前
|
SQL Java 数据库连接
Springboot框架整合Spring JDBC操作数据
JDBC是Java数据库连接API,用于执行SQL并访问多种关系数据库。它包括一系列Java类和接口,用于建立数据库连接、创建数据库操作对象、定义SQL语句、执行操作并处理结果集。直接使用JDBC涉及七个步骤,包括加载驱动、建立连接、创建对象、定义SQL、执行操作、处理结果和关闭资源。Spring Boot的`spring-boot-starter-jdbc`简化了这些步骤,提供了一个在Spring生态中更便捷使用JDBC的封装。集成Spring JDBC需要添加相关依赖,配置数据库连接信息,并通过JdbcTemplate进行数据库操作,如插入、更新、删除和查询。
|
14天前
|
SQL Java 数据库连接
Springboot框架整合Spring Data JPA操作数据
Spring Data JPA是Spring基于ORM和JPA规范封装的框架,简化了数据库操作,提供增删改查等接口,并可通过方法名自动生成查询。集成到Spring Boot需添加相关依赖并配置数据库连接和JPA设置。基础用法包括定义实体类和Repository接口,通过Repository接口可直接进行数据操作。此外,JPA支持关键字查询,如通过`findByAuthor`自动转换为SQL的`WHERE author=?`查询。
|
18天前
|
Java Maven Docker
0.07 秒启动一个 SpringBoot 项目!Spring Native 很强!!
0.07 秒启动一个 SpringBoot 项目!Spring Native 很强!!
26 2
|
20天前
|
前端开发 Java Spring
[AIGC] Spring Interceptor 拦截器详解
[AIGC] Spring Interceptor 拦截器详解
|
20天前
|
Java Maven 数据库
Spring Boot Starter: 快速简明地创建Spring应用
Spring Boot Starter: 快速简明地创建Spring应用
|
前端开发 Java 开发工具
Spring 拦截器|学习笔记
快速学习 Spring 拦截器
Spring 拦截器|学习笔记
|
2月前
|
Java 应用服务中间件 Maven
SpringBoot 项目瘦身指南
SpringBoot 项目瘦身指南
55 0