一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

SpringBoot拦截器怎么用?从入门到多拦截器链式调用详细说明

时间:2026-08-06 07:36:57 编辑:袖梨 来源:一聚教程网

SpringBoot拦截器怎么用?从入门到多拦截器链式调用详细说明需要先看清适用场景和关键步骤,避免只记结论却忽略实际限制。

前言

在现代的 Spring Boot 应用开发中,拦截器(Interceptor)是一个非常重要的机制。

SpringBoot拦截器怎么用?从入门到多拦截器链式调用详解

它位于客户端请求到达 Controller 之前响应返回之后的中间环节,可以帮助开发者在请求处理流程中插入自定义逻辑,实现对请求的预处理和后处理。

拦截器的主要作用包括:

  1. 请求预处理:如身份认证、权限校验、日志记录、请求参数统一处理等。

  2. 响应后处理:如对返回结果进行统一包装、清理资源等。

  3. 异常处理和性能监控:可以统计接口调用耗时,捕获并处理异常信息。

常见的应用场景有:

  1. 用户登录状态验证,拦截未登录用户访问受限接口;

  2. 接口访问日志记录,方便审计和问题排查;

  3. 请求参数校验和统一格式化;

  4. 跨域请求处理和安全防护;

  5. 性能监控和统计接口响应时间。

通过拦截器,可以在不改变业务代码的前提下,实现全局且统一的请求处理逻辑,提升应用的维护性和安全性。

概括来看,就是在请求进入 Controller 前后,把一些必要的通用逻辑统一起来,使得代码维护更方便。

1. 拦截器的核心接口与原理

在 Spring Boot 中,拦截器本质上是通过实现 Spring MVC 提供的 HandlerInterceptor 接口来完成的。它允许我们在请求进入 Controller 前、请求处理后、以及请求完成后分别插入自定义逻辑,适用于权限校验、日志记录、性能监控等场景。

拦截器的执行流程

 Client Request       ↓   preHandle()       ↓        (如果返回 true)   Controller   (调用 Service 层处理业务)       ↓  postHandle()       ↓    视图渲染       ↓afterCompletion()       ↓ Client Response

以上流程为简化示意,便于理解拦截器的执行顺序。实际底层还涉及 Servlet 容器对请求和响应的处理,以及 Spring MVC 内部多层调用。

HandlerInterceptor接口的三个核心方法

/** * 在控制器方法执行前调用。 * 可用于权限认证、参数校验、日志记录等。 * 返回 false 会终止请求流程,后续的拦截器和 Controller 都不会被执行。 */boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler);
/** * 控制器方法执行后、视图渲染之前调用。 * 可用于修改 ModelAndView,实现页面统一封装等功能。 */void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView);
/** * 请求处理完成后(视图渲染之后)调用。 * 可用于资源清理、异常处理、日志收集等。 */ void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex);

HttpServletRequest 可用于获取请求相关信息(如请求路径、参数、Header 等),而 HttpServletResponse 可用于设置响应内容(如状态码、响应头、输出数据等)。

注意:preHandlepostHandleafterCompletion 都由 Spring 框架自动在请求生命周期中调用,对业务代码来说是不可见的中间处理逻辑

2. 示例:创建一个简单的拦截器

本节,通过一个简单示例,展示如何自定义一个拦截器并实现基本的请求日志记录功能。

创建一个类实现 HandlerInterceptor,并重写所需的方法,比如 preHandle,用于在请求到达 Controller 前打印日志:

import jakarta.servlet.http.HttpServletRequest;import jakarta.servlet.http.HttpServletResponse;import org.springframework.web.servlet.HandlerInterceptor;public class LoggingInterceptor implements HandlerInterceptor {    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {        System.out.println("请求URL:" + request.getRequestURI() + " | 方法:" + request.getMethod());        // 返回 true 表示继续流程(放行),返回 false 则中断请求        return true;    }    // 可根据需要重写 postHandle 和 afterCompletion 方法}

登录拦截器通常会从请求头中获取 token,解析后将用户信息存入 ThreadLocal,实现用户登录状态的维护与传递。

3. 示例:拦截器的注册与配置

在创建好拦截器类后,需要将其注册到 Spring MVC 的拦截器链中,才能生效。通常通过实现 WebMvcConfigurer 接口的 addInterceptors 方法完成注册和配置。

创建一个配置类,实现 WebMvcConfigurer,并重写 addInterceptors 方法,添加自定义拦截器:

import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configurationpublic class WebConfig implements WebMvcConfigurer {    @Override    public void addInterceptors(InterceptorRegistry registry) {        registry.addInterceptor(new LoggingInterceptor())                .addPathPatterns("/**")      // 拦截所有请求                .excludePathPatterns("/login", "/register"); // 排除特定路径    }}

说明:

  1. addPathPatterns 用于指定拦截器拦截的 URL 路径模式,支持通配符。
  2. excludePathPatterns 用于排除某些路径不被拦截,常用于登录、静态资源等。
  3. 可以注册多个拦截器,按照添加顺序依次执行。

WebConfig 类记得添加 @Configuration 注解,Spring 框架才会识别并加载该配置。

4. 多拦截器链式调用

在实际项目中,通常会注册多个拦截器组成一个“拦截器链”,请求会依次经过每个拦截器的 preHandlepostHandleafterCompletion 方法。理解多拦截器的执行顺序,有助于合理设计拦截器的职责和调用时机。

执行顺序:

假设按顺序注册了拦截器 A、B、C,执行顺序如下:

  1. 请求进入,先按注册顺序依次调用各拦截器的 preHandle 方法:A → B → C
  2. 业务处理(Controller)执行
  3. 响应返回,按注册顺序反向调用各拦截器的 postHandle 方法:C → B → A
  4. 请求完成后,按注册顺序反向调用各拦截器的 afterCompletion 方法:C → B → A

特殊情况说明:

  1. 任何一个拦截器的 preHandle 返回 false,后续的拦截器和 Controller 都不会执行,直接中断请求。
  2. afterCompletion 方法无论请求是否正常完成都会被调用,用于清理资源。

示例代码(简化):

public class InterceptorA implements HandlerInterceptor {    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {        System.out.println("A preHandle");        return true;    }    @Override    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {        System.out.println("A postHandle");    }    @Override    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {        System.out.println("A afterCompletion");    }}// InterceptorB 和 InterceptorC 类似

5. 拦截器与过滤器的区别

1. 作用层级不同

  1. 过滤器(Filter) 是基于 Servlet 规范实现的,属于 Servlet 容器层面的组件,能拦截所有到达应用的请求,包括静态资源和动态请求。
  2. 拦截器(Interceptor) 是 Spring MVC 的一部分,作用于 Spring 的 DispatcherServlet 之后,主要拦截控制器(Controller)的方法调用,只针对处理器映射的请求起作用。

2. 生命周期和调用时机

  1. 过滤器在请求进入应用时最早执行,可以在 Servlet 容器层对请求进行修改或阻断。
  2. 拦截器是在 Handler 执行之前和之后执行,能够访问 Handler 的具体信息,适合做业务相关的处理。

3. 功能侧重点

  1. 过滤器更适合做通用的请求过滤、编码设置、压缩、日志记录、安全检查等与底层协议相关的处理。
  2. 拦截器适合做业务层面的权限控制、日志记录、性能监控、参数绑定预处理等。

4. 配置方式

  1. 过滤器需要在 web.xml 中配置,或者通过代码注册(FilterRegistrationBean),相对底层。
  2. 拦截器通过实现 HandlerInterceptor 并注册到 Spring MVC 配置中,配置更简洁且与 Spring 框架集成紧密。

5. 是否支持异步处理

  1. 过滤器对异步请求的支持有限。
  2. 拦截器在 Spring MVC 中对异步请求支持更好,能够处理异步请求的生命周期。

过滤器更偏底层、范围更广;拦截器偏 Spring MVC 层面,更加聚焦于业务处理。两者常结合使用,互为补充。

6. 总结

  1. 实现拦截器只需定义一个类实现 HandlerInterceptor 接口,并重写其中的方法,然后通过实现 WebMvcConfigurer 接口在 addInterceptors 方法中注册拦截器。

  2. 多个拦截器的调用顺序为:preHandle 方法按注册顺序执行,postHandleafterCompletion 方法按注册顺序的反向执行。

  3. 过滤器是 Servlet 规范的一部分,运行于底层 Servlet 容器,作用范围更广;拦截器是 Spring MVC 特有,专注于处理请求和响应,能访问 Handler。

  4. 过滤器适合做通用功能(如日志、编码、安全等),拦截器适合做权限校验、请求处理和视图渲染前后操作,两者在实际项目中常常配合使用。

热门栏目