Spring Boot 拦截器(Interceptor)与过滤器(Filter)有什么区别?

在 Spring Boot 项目中,我们经常会遇到需要在请求处理前后执行一些通用逻辑的场景,比如记录日志、权限校验、全局异常处理等。此时,我们通常会面临两种选择:过滤器(Filter)拦截器(Interceptor)

虽然两者都能实现类似的功能,但它们在实现原理、使用场景、执行时机等方面有着本质的区别。本文将带你深入剖析这两者的差异,并通过实战案例,让你彻底搞懂何时该用过滤器,何时该用拦截器。

在这里插入图片描述

一、核心概念:从根上理解它们的区别

1.1 过滤器(Filter)

  • 规范层级:属于 Java Servlet 规范 的一部分,由 Servlet 容器(如 Tomcat)直接管理。
  • 作用范围:对整个 Web 应用生效,包括静态资源(如 HTML、CSS、JS 等)。
  • 触发时机:在请求进入 DispatcherServlet 之前,以及响应返回客户端之后。
  • 依赖关系:不依赖 Spring 容器,可以脱离 Spring 独立使用。

1.2 拦截器(Interceptor)

  • 规范层级:Spring MVC 框架提供的机制,由 Spring 容器管理。
  • 作用范围:仅对 Spring MVC 控制器(Controller) 的请求生效,默认不拦截静态资源。
  • 触发时机:在请求进入 DispatcherServlet 之后,到达 Controller 之前,以及 Controller 处理完请求之后。
  • 依赖关系:深度集成 Spring 容器,可以方便地使用 Spring 的依赖注入(DI)和 AOP 功能。
特性对比过滤器(Filter)拦截器(Interceptor)
规范层级Java Servlet 规范Spring MVC 框架
作用范围所有请求(包括静态资源)仅 Controller 请求
触发时机DispatcherServlet 前后Controller 前后
依赖容器Servlet 容器Spring 容器
能否修改请求/响应可以直接修改不能直接修改,但可操作 Model 和 View

二、执行流程:一个图看懂它们的调用顺序

为了更直观地理解两者的执行顺序,我们来看一张经典的流程图:

HTTP Request↓
Filter Chain(doFilter)↓
DispatcherServlet↓
Interceptor.preHandle↓
Controller Method↓
Interceptor.postHandle↓
View Rendering(如有)↓
Interceptor.afterCompletion↓
Filter Chain(返回响应)

从这个流程可以看出:

  • 过滤器 是最外层的“大门”,所有请求都必须经过它。
  • 拦截器 是内层的“小门”,只对进入 Spring MVC 的请求生效。

三、实战演练:代码说话最真实

3.1 过滤器(Filter)实战:记录请求耗时

@Component
public class LogFilter implements Filter {private static final Logger logger = LoggerFactory.getLogger(LogFilter.class);@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {long startTime = System.currentTimeMillis();HttpServletRequest httpRequest = (HttpServletRequest) request;logger.info("请求开始,URI: {}", httpRequest.getRequestURI());chain.doFilter(request, response); // 放行请求long duration = System.currentTimeMillis() - startTime;logger.info("请求结束,耗时: {}ms", duration);}
}

3.2 拦截器(Interceptor)实战:登录权限校验

@Component
public class AuthInterceptor implements HandlerInterceptor {@Autowiredprivate AuthService authService; // 可以注入Spring Bean@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String token = request.getHeader("Authorization");if (!authService.isValidToken(token)) {response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);return false; // 拦截请求}return true; // 放行请求}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {logger.info("Controller 方法执行完毕,准备渲染视图");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {logger.info("请求处理完成,资源清理");}
}

3.3 配置拦截器到Spring容器

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {@Autowiredprivate AuthInterceptor authInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(authInterceptor).addPathPatterns("/api/**") // 拦截所有 /api 开头的请求.excludePathPatterns("/api/login"); // 排除登录接口}
}

四、选型指南:什么时候用过滤器,什么时候用拦截器?

场景需求推荐方案
需要处理静态资源(如HTML、CSS、JS)过滤器(Filter)
需要最早拦截请求(如全局跨域处理)过滤器(Filter)
需要访问Spring Bean(如Service、Repository)拦截器(Interceptor)
需要精确控制Controller方法的执行前后拦截器(Interceptor)
需要修改请求和响应的内容(如压缩、编码)过滤器(Filter)

五、常见误区与最佳实践

5.1 常见误区

  • 误区1:拦截器可以处理静态资源
    实际上,拦截器默认不会拦截静态资源,除非你手动配置了 addResourceHandler

  • 误区2:过滤器可以直接使用Spring Bean
    过滤器由Servlet容器管理,默认无法使用Spring的依赖注入。可以通过 DelegatingFilterProxy 桥接,但配置较复杂。

  • 误区3:拦截器可以修改请求参数
    拦截器无法直接修改请求参数,如需修改,需使用过滤器配合 HttpServletRequestWrapper

5.2 最佳实践

  • 优先使用拦截器:除非必须处理静态资源或需要最早拦截,否则优先使用拦截器,因为它更贴近业务逻辑,且易于测试。
  • 避免复杂逻辑:无论是过滤器还是拦截器,都应避免复杂的业务逻辑,以免影响性能。
  • 合理配置顺序:如果同时使用多个过滤器或拦截器,务必注意它们的执行顺序,避免逻辑冲突。

六、总结:一句话记住它们的区别

过滤器(Filter)是 Servlet 的“大门”,拦截器(Interceptor)是 Spring MVC 的“小门”。

  • Filter:更早、更底层、更通用,但离业务逻辑较远。
  • Interceptor:更晚、更上层、更灵活,更贴近业务逻辑。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/921707.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/921707.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【技术教程】如何将文档编辑器集成至基于Java的Web应用程序

在如今的企业协作场景中,“文档” 早已不是简单的文字载体!从项目需求文档的多人实时修改,到财务报表的在线批注,再到合同草案的版本追溯,用户越来越需要在 Web 应用内直接完成 “编辑 - 协作 - 存储” 全流程。 但很…

多模态大模型Keye-VL-1.5发布!视频理解能力更强!

近日,快手正式发布了多模态大语言模型Keye-VL-1.5-8B。 与之前的版本相比,Keye-VL-1.5的综合性能实现显著提升,尤其在基础视觉理解能力方面,包括视觉元素识别、推理能力以及对时序信息的理—表现尤为突出。Keye-VL-1.5在同等规模…

洗完头后根据个人需求选择合适的自然风干 | 电吹风 (在保护发质的同时,也能兼顾到生活的便利和舒适。)

文章目录 引言 I 选合适的方式让头发变干 时间充裕,不需要做造型,选择自然风干 使用电吹风,比较推荐的做法 II 自然风干 天冷可能刺激头皮 III 电吹风吹干 容易造型 影响头皮健康 损伤发质 科普 头皮的微观结构 头发丝 引言 吹风吹干:容易造型,但损伤发质、影响头皮健康 …

GPS汽车限速器有哪些功能?主要运用在哪里?

GPS 汽车限速器是一种结合全球卫星定位(GPS)技术、车速采集技术与车辆控制 / 预警逻辑的设备,核心目标是通过技术手段限制车辆行驶速度,减少超速引发的交通事故,并辅助车辆管理。其功能与应用场景高度匹配不同用户的 “…

Python从入门到精通_01_python基础

1 源代码格式在python文件的第一行,输入以下语句,可以将python文件的编码格式设置为utf-8#-*- coding:utf-8 -*-2 输入输出input():输入,无论输入的是什么类型数据,最后都是字符串类型print(*args, sep , end\n, fileNone, flushF…

使用CI/CD部署项目(前端Nextjs)

写在前面:在github上使用CI/CD部署Nextjs项目,具体配置可以按照自己的实际的修改 这是我的项目配置,仅供参考 后端项目可以参考:使用CI/CD部署后端项目 正文开始 项目名(PROJECT_NAME)- CI/CD 部署指南…

Java全栈工程师面试实录:从基础到实战的全面解析

Java全栈工程师面试实录:从基础到实战的全面解析 面试官:李明(资深技术负责人) 应聘者:张宇(28岁,硕士学历,5年开发经验) 第一轮:Java语言与JVM基础 李明&…

C#中解析XML时遇到注释节点报错

在C#中解析XML时遇到注释节点报错的问题&#xff0c;这是因为XML注释节点&#xff08;<!-- -->&#xff09;是特殊的节点类型。当遍历XML节点时&#xff0c;注释节点也会被包含在内&#xff0c;但它们不能像普通元素节点那样处理。 解决方案 方法1&#xff1a;跳过注释节…

9.3深度循环神经网络

目前为止&#xff0c;只讨论了具有一个单向隐藏层的循环神经网络&#xff0c;其中隐变量和观测值域具体的函数形式的交互方式是相当随意的。只要交互类型建模具有足够的灵活性&#xff0c;不是一个单问题。然而&#xff0c;对一个单层来说&#xff0c;可能具有相当的挑战性。之…

CSS in JS 的演进:Styled Components, Emotion 等的深度对比与技术选型指引

CSS in JS 的演进&#xff1a;Styled Components, Emotion 等的深度对比与技术选型指引在现代前端开发中&#xff0c;组件化思维已成为主流&#xff0c;而如何科学、高效地管理组件的样式&#xff0c;也随之成为了一个重要议题。CSS in JS&#xff08;JS中的CSS&#xff09;应运…

【正则表达式】 正则表达式的分组和引用

🌈 个人主页:(时光煮雨) 🔥 高质量专栏:vulnhub靶机渗透测试 👈 希望得到您的订阅和支持~ 💡 创作高质量博文(平均质量分95+),分享更多关于网络安全、Python领域的优质内容!(希望得到您的关注~) 🌵目录🌵 前言 🍱一、基本语法 🍘二、分组类型 🍙2.1.…

Grafana 导入仪表盘失败:从日志排查到解决 max\_allowed\_packet 问题

问题背景 近期在为项目搭建一套基于 Prometheus 和 Grafana 的可观测性体系。在完成基础部署后&#xff0c;我准备导入一个功能相对复杂的官方仪表盘模板&#xff0c;以便快速监控各项指标。然而&#xff0c;当上传仪表盘的 JSON 文件并点击保存时&#xff0c;Grafana 界面却反…

java对接物联网设备(一)——使用okhttp网络工具框架对接标准API接口

当前无论是在互联网领域&#xff0c;还是物联网项目下&#xff0c;亦或者各类应用类软件&#xff0c;基于http标准接口的对接是目前市面上最常见也是最简单的数据交互方式之一&#xff0c;甚至可以说是最流行的&#xff0c;因为它不依赖的各种插件或者服务。 开发者或者提供服…

版本管理系统与平台(权威资料核对、深入解析、行业选型与国产平台补充)

本文是一篇基于公开权威资料&#xff08;官方文档、产品页、厂商技术文章与技术社区讨论&#xff09;重新检索、核对后撰写的详尽博文。内容覆盖&#xff1a;版本控制基础、主流 VCS 工具深度比较、常见托管/协作平台&#xff08;含中国本土平台&#xff1a;Gitee / GitCode / …

计算机毕设选题:基于Python+Django的B站数据分析系统的设计与实现【源码+文档+调试】

精彩专栏推荐订阅&#xff1a;在 下方专栏&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f496;&#x1f525;作者主页&#xff1a;计算机毕设木哥&#x1f525; &#x1f496; 文章目录 一、项目介绍二…

Easy ES技术详解

从Java代码示例到高级特性 框架介绍 Easy-Es 是一款以 “简化 Elasticsearch 操作的 ORM 框架” 为核心定位的开源工具&#xff0c;旨在通过低代码设计降低 Elasticsearch 的使用门槛。作为国内 Top1 Elasticsearch 搜索引擎框架&#xff0c;其最显著的优势在于大幅缩减代码量…

【51单片机】【protues仿真】基于51单片机停车场的车位管理系统

目录 一、主要功能 二、使用步骤 三、硬件资源 四、软件设计 五、实验现象 一、主要功能 1、LCD1602液晶显示 2、统计并显示停车场现有车辆数和已停放过车辆数 3、按键设置总车位数以及剩余车位数 4、统计并显示累计驶入和累计驶出车辆数 5、用16个LED灯模拟停车位 6、车…

【Python】S1 基础篇 P4 if 语句指南

目录简单示例条件测试检查是否相等与不等检查多个条件检查特定的值是否在/不在列表中布尔表达式if语句简单的if语句if-else语句if-elif-else语句使用if语句处理列表检查特殊元素确定列表非空使用多个列表总结if 语句是Python编程中最基本也是最重要的控制结构之一。它允许程序根…

【实战中提升自己】内网安全部署之STP的安全技术部署

1 1拓扑 「模拟器、工具合集」复制整段内容 链接&#xff1a;https://docs.qq.com/sheet/DV0xxTmFDRFVoY1dQ?tab7ulgil1 STP的安全技术部署 说明&#xff1a;为什么需要注意STP的安全呢&#xff0c;在二层中其实存在很多不安全的因素&#xff0c;物理上…

GEM5学习(5): ARM 架构功耗仿真

运行脚本基于gem5提供的脚本&#xff0c;启动功耗仿真。实际工作中应该不会用gem5进行功耗的仿真吧&#xff0c;Cadence和Synopsys好像都有配套的的功耗建模工具。事先要配置好 IMG_ROOT的环境变量./build/ARM/gem5.opt configs/example/arm/fs_power.py \--caches \--bootl…