Spring Boot拦截器(Interceptor)与过滤器(Filter)深度解析:区别、实现与实战指南
Spring Boot拦截器(Interceptor)与过滤器(Filter)深度解析:区别、实现与实战指南
一、核心概念对比
1. 本质区别
| 维度 | 过滤器(Filter) | 拦截器(Interceptor) |
|---|---|---|
| 规范层级 | Servlet规范(J2EE标准) | Spring MVC框架机制 |
| 作用范围 | 所有请求(包括静态资源) | 只处理Controller请求 |
| 依赖关系 | 不依赖Spring容器 | 完全集成Spring IOC容器 |
| 执行顺序 | 最先执行(在DispatcherServlet之前) | 在DispatcherServlet之后执行 |
| 异常处理 | 无法直接使用Spring的异常处理机制 | 可以通过@ControllerAdvice统一处理 |
2. 执行流程示意图
HTTP Request↓
Filter Chain(doFilter)↓
DispatcherServlet↓
Interceptor.preHandle↓
Controller Method↓
Interceptor.postHandle↓
View Rendering(如有)↓
Interceptor.afterCompletion↓
Filter Chain(返回响应)
二、过滤器(Filter)开发指南
1. 基础实现方式
@Component
public class LogFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {long startTime = System.currentTimeMillis();HttpServletRequest req = (HttpServletRequest) request;// 前置处理System.out.println("Request URI: " + req.getRequestURI());chain.doFilter(request, response); // 放行请求// 后置处理long duration = System.currentTimeMillis() - startTime;System.out.println("Request completed in " + duration + "ms");}
}
2. 高级配置技巧
@Configuration
public class FilterConfig {@Beanpublic FilterRegistrationBean<LogFilter> loggingFilter() {FilterRegistrationBean<LogFilter> registration = new FilterRegistrationBean<>();registration.setFilter(new LogFilter());registration.addUrlPatterns("/api/*");registration.setOrder(Ordered.HIGHEST_PRECEDENCE); // 设置优先级return registration;}
}
典型应用场景:
- 请求日志记录
- 全局字符编码设置
- 跨域处理(CORS)
- XSS防御过滤
- 请求内容压缩/解压
三、拦截器(Interceptor)开发指南
1. 标准实现模板
@Component
public class AuthInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String token = request.getHeader("Authorization");if (!validateToken(token)) {response.sendError(401, "Invalid token");return false; // 中断请求}return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {// Controller方法执行后,视图渲染前}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// 请求完全结束后(包括视图渲染)}
}
2. 注册拦截器配置
@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate AuthInterceptor authInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(authInterceptor).addPathPatterns("/**").excludePathPatterns("/login", "/public/**");}
}
典型应用场景:
- 接口权限验证
- 请求参数预处理
- 接口耗时监控
- 敏感操作日志
- 数据绑定前校验
四、核心差异深度解析
1. 执行顺序对比实验
配置多个过滤器和拦截器时的执行顺序:
Filter1 → Filter2 → Interceptor.preHandle
→ Controller
→ Interceptor.postHandle
→ Interceptor.afterCompletion
→ Filter2 → Filter1
2. 异常处理差异
// 在过滤器中处理异常
public void doFilter(...) {try {chain.doFilter(request, response);} catch (Exception e) {response.sendError(500, "Server Error");}
}// 在拦截器中处理异常
@ControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(Exception.class)public ResponseEntity<?> handleException(Exception e) {return ResponseEntity.internalServerError().body("Error occurred");}
}
3. 异步请求处理
// 拦截器需实现AsyncHandlerInterceptor
@Override
public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) {// 异步请求的特殊处理
}
五、最佳实践与选型策略
1. 技术选型决策树
是否需要处理静态资源?
├─ 是 → 必须使用Filter
└─ 否 → 是否需要访问Spring Bean?├─ 是 → 选择Interceptor└─ 否 → 是否需要最早处理请求?├─ 是 → 选择Filter└─ 否 → 根据业务复杂度选择
2. 性能优化建议
- 过滤器:避免在过滤器中做复杂业务逻辑
- 拦截器:preHandle方法尽量轻量化
- 两者都应避免:
- 同步阻塞操作
- 频繁的IO操作
- 大对象的内存操作
3. 常见陷阱规避
- 过滤器:
- 忘记调用chain.doFilter()导致请求阻塞
- 修改请求参数未使用Wrapper类
- 拦截器:
- 在postHandle中修改ModelAndView导致NPE
- 异步请求中误用afterCompletion
六、实战案例演示
案例1:接口耗时监控系统
// 拦截器实现
public class MetricsInterceptor implements HandlerInterceptor {private static final ThreadLocal<Long> startTime = new ThreadLocal<>();@Overridepublic boolean preHandle(...) {startTime.set(System.currentTimeMillis());return true;}@Overridepublic void afterCompletion(...) {long duration = System.currentTimeMillis() - startTime.get();metricsService.recordRequestTime(request.getRequestURI(), duration);startTime.remove();}
}
案例2:全局防重放攻击过滤器
public class ReplayAttackFilter implements Filter {private Cache<String, Boolean> requestCache = Caffeine.newBuilder().expireAfterWrite(5, TimeUnit.MINUTES).build();@Overridepublic void doFilter(...) {String nonce = request.getHeader("X-Nonce");if (requestCache.getIfPresent(nonce) != null) {response.sendError(400, "Duplicate request");return;}requestCache.put(nonce, true);chain.doFilter(request, response);}
}
七、扩展知识
1. 与AOP的区别
- AOP:
- 基于代理模式实现
- 可以精确控制到具体方法
- 更适合业务层面的切面处理
- 拦截器:
- 基于HandlerMapping实现
- 主要针对HTTP请求生命周期
- 更适合Web层通用处理
2. 高级应用场景
- 过滤器链:实现责任链模式
- 拦截器栈:组合多个拦截逻辑
- 动态启用/禁用:结合配置中心实现
总结建议
- 优先使用拦截器处理Web层通用逻辑
- 保留过滤器用于底层请求处理
- 复杂场景可以组合使用两者
- 生产环境务必进行性能压测
通过合理运用过滤器和拦截器,开发者可以构建出高可维护性的Web应用架构。建议结合APM工具(如SkyWalking)监控两者的执行效率,持续优化系统性能。
相关文章:
Spring Boot拦截器(Interceptor)与过滤器(Filter)深度解析:区别、实现与实战指南
Spring Boot拦截器(Interceptor)与过滤器(Filter)深度解析:区别、实现与实战指南 一、核心概念对比 1. 本质区别 维度过滤器(Filter)拦截器(Interceptor)规范层级Serv…...
模运算的艺术:从基础到高阶的算法竞赛应用
在算法竞赛中,模运算(取模运算)是一个非常重要的概念,尤其在处理大数、防止溢出、以及解决与周期性相关的问题时。C 中的模运算使用 % 运算符,但它的行为和使用场景需要特别注意。 1. 模运算的基本概念 模运算是指求一…...
Java 并发编程——Java BIO NIO Socket编程
参考Java 并发编程——Java BIO NIO Socket编程 BIO:阻塞式编程模型 Socket 服务端编程Socket 客户端编程 NIO:非阻塞式编程模型 NIO 介绍Java 中 NIO 非阻塞式与前面 BIO 阻塞式的区别Java NIO类库包含以下三个核心组件ServerSocketChannel 服务端编程…...
ST电机库电流采样 三电阻单ADC
一、概述 下图是三电阻采样的电路结构 其中流过三相系统的电流I1、I2、I3遵循以下关系: 因此,为了重建流过普通三相负载的电流,在我们可以用以上公式计算的情况下,只需要对三相中的两相进行采样即可。 STM32的ADC可以很灵活的配置成同步采集两路ADC数据,…...
【网络】什么是 IHL(Internet Header Length,首部长度)TTL(Time To Live,生存时间)?
在 IPv4 数据报文中,IHL(Internet Header Length,首部长度)、TTL(Time To Live,生存时间) 和 TIL 涉及到 IP 数据包的结构和生命周期。以下是对它们的详细解释: 📌 1. IH…...
现代密码学 | 具有保密和认证功能的安全方案
1.案例背景 1.1 2023年6月,微软云电子邮件泄露 事件描述: 2023年6月,属于多家美国政府机构的微软云电子邮件账户遭到非法入侵,其中包括了多位高级政府官员的电子邮件。据报道,美国国务院的10个邮件账户中共有6万封电…...
一款基于Python的从常规文档里提取图片的简单工具开发方案
一款基于Python的从常规文档里提取图片的简单工具开发方案 1. 环境准备 安装必需库 pip install python-docx PyMuPDF openpyxl beautifulsoup4 pillow pip install pdfplumber # PDF解析备用方案 pip install tk # Python自带,无需安装工具选择 开发环…...
JetBrains(全家桶: IDEA、WebStorm、GoLand、PyCharm) 2024.3+ 2025 版免费体验方案
JetBrains(全家桶: IDEA、WebStorm、GoLand、PyCharm) 2024.3 2025 版免费体验方案 前言 JetBrains IDE 是许多开发者的主力工具,但从 2024.02 版本起,JetBrains 调整了试用政策,新用户不再享有默认的 30 天免费试用…...
Pytorch实现之BCGAN实现双生成器架构的人脸面部生成
简介 简介:通过双生成器架构与重建损失进行循环的生成训练,实现人脸面部表情合成。 论文题目:BCGAN: Facial Expression Synthesis by Bottleneck-Layered Conditional Generative Adversarial Networks (基于瓶颈分层条件生成对抗网络的面部表情合成) 会议:2021 15th…...
智慧加油站小程序数据库设计文档
智慧加油站系统 - 数据库与API设计文档 1. 数据库设计 1.1 ER模型 系统的核心实体关系如下: 用户(User) ---< 订单(Order) ---< 加油记录(RefuelRecord)| | || | vv v …...
Docker生存手册:安装到服务一本通
文章目录 一. Docker 容器介绍1.1 什么是Docker容器?1.2 为什么需要Docker容器?1.3 Docker架构1.4 Docker 相关概念1.5 Docker特点 二. Docker 安装2.1 查看Linux内核版本2.2 卸载老版本docker,避免产生影响2.3 升级yum 和配置源2.4 安装Dock…...
Linux内核传输层UDP源码分析
一、用户数据包协议(UDP) 1.UDP数据报头 UDP 提供面向消息的不可靠传输,但没有拥塞控制功能。很多协议都使用 UDP,如用于 IP 网络传输音频和视频的实时传输协议 (Real-time Transport Protocol,RTP),此类型…...
FPGA学习(二)——实现LED流水灯
FPGA学习(二)——实现LED流水灯 目录 FPGA学习(二)——实现LED流水灯一、DE2-115时钟源二、控制6个LED灯实现流水灯1、核心逻辑2、代码实现3、引脚配置4、实现效果 三、模块化代码1、分频模块2、复位暂停模块3、顶层模块 四、总结 一、DE2-115时钟源 DE2-115板子包含一个50MHz…...
E1-最远距离(stl使用)
题目描述 给定一个数组,请你找出数组中相同元素之间的最远距离。若数组中不存在相同元素,则输出 null。 输入描述 输入一个数组,数组长度不超过 10000。格式请见用例。 输出描述 输出数组中相同元素的最远距离。 用例 输入 [3, 2, 3,…...
Linux如何在设备树中表示和引用设备信息
DTS基本知识 dts 硬件的相应信息都会写在.dts为后缀的文件中,每一款硬件可以单独写一份xxxx.dts,一般在Linux源码中存在大量的dts文件,对于arm架构可以在arch/arm/boot/dts找到相应的dts,一个dts文件对应一个ARM的machie。 dtsi 值…...
Matlab 汽车振动多自由度非线性悬挂系统和参数研究
1、内容简介 略 Matlab 169-汽车振动多自由度非线性悬挂系统和参数研究 可以交流、咨询、答疑 2、内容说明 略 第二章 汽车模型建立 2.1 汽车悬架系统概述 2.1.1 悬架系统的结构和功能 2.1.2 悬架分类 2.2 四分之一车辆模型 对于车辆动力学,一般都是研究其悬…...
Maven核心包:maven-resolver-api
在阅读 nexus-pubic 开源项目过程中,使用了大量的核心组件进行轻量化集成。它的这种构建方式,在阅读过程中不得不感概,节省成本从构建项目的方式上就遥遥领先了。但是 maven核心包,依然使用前几年的aether-spi,却没有更…...
生活中的可靠性小案例11:窗户把手断裂
窗户把手又断了,之前也断过一次,使用次数并没有特别多。上方的图是正常的把手状态,断的形状如下方图所示。 这种悬臂梁结构,没有一个良好的圆角过渡,导致应力集中。窗户的开关,对应的是把手的推拉ÿ…...
[oeasy]python074_ai辅助编程_水果程序_fruits_apple_banana_加法_python之禅
074_ai辅助编程_水果程序_fruits_加法 回忆上次内容 上次直接从模块中导入变量、函数 from my_file import pi 导入my_file.pi 并作为 pi 使用 from my_file import pi as my_pi 导入变量 并 重命名 添加图片注释,不超过 140 字(可选) …...
【图论】并查集的学习和使用
目录 并查集是什么? 举个例子 组成 父亲数组: find函数: union函数: 代码实现: fa[] 初始化code: find code: 递归实现: 非递归实现: union code : 画图模拟: 路径压缩:…...
欢乐力扣:反转链表
文章目录 1、题目描述2、思路 1、题目描述 反转链表。 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 2、思路 借助cur指针和pre双指针来调整链表的前后指向。 # Definition for singly-linked list. # class ListNode: # def __i…...
1.8PageTable
页表的作用 虚拟地址空间映射:页表记录了进程的虚拟页号到物理页号的映射关系。每个进程都有自己的页表,操作系统为每个进程维护一个独立的页表。内存管理:页表用于实现虚拟内存管理,支持进程的虚拟地址空间和物理地址空间之间的…...
什么是大带宽服务器
什么是大带宽服务器? 在深入探讨大带宽之前,让我们先明确带宽的概念。带宽与我们日常所说的宽带有所不同,宽带是运营商为满足家庭或商业上网需求所提供的服务,而带宽则特指数据的传输速度,尤其是上行速度。大带宽服务…...
【TCP】三次挥手,四次挥手详解--UDP和TCP协议详解
活动发起人小虚竹 想对你说: 这是一个以写作博客为目的的创作活动,旨在鼓励大学生博主们挖掘自己的创作潜能,展现自己的写作才华。如果你是一位热爱写作的、想要展现自己创作才华的小伙伴,那么,快来参加吧!…...
Compose 实践与探索十二 —— 附带效应
1、SideEffect Google 官方文档对 side effect 有两种翻译,简体中文翻译为附带效应,繁体中文翻译为副作用。这两个翻译我们用哪个都行,关键是如何理解它的含义。 1.1 什么是副作用 我们在日常生活中听到的副作用大多是医学领域中的&#x…...
Kubernetes 控制平面详解 —— 探秘 API Server、Controller Manager、Scheduler 与 etcd
文章目录 Kubernetes 控制平面详解 —— 探秘 API Server、Controller Manager、Scheduler 与 etcd控制平面概述API Server角色与职责工作原理 etcd角色与职责工作原理 Scheduler角色与职责工作原理 Controller Manager角色与职责工作原理 总结 Kubernetes 控制平面详解 —— 探…...
SSM基础专项复习4——Maven项目管理工具(1)
系列文章 1、SSM基础专项复习1——SSM项目整合-CSDN博客 2、SSM基础专项复习2——Spring 框架(1)-CSDN博客 3、SSM基础专项复习3——Spring框架(2)-CSDN博客 文章目录 系列文章 1. Maven 的概念 1.1. 什么是 Maven 1.2. 什…...
使用c#进行串口通信
一、串口通信协议 1.串口通信协议简介 串口通信(serial communication)是一种设备间非常常用的串行通信方式,大部分电子设备都支持,电子工程师再调试设备时也经常使用该通信方式输出调试信息。讲到某一种通信协议,离…...
Web开发-PHP应用鉴别修复AI算法流量检测PHP.INI通用过滤内置函数
知识点: 1、安全开发-原生PHP-PHP.INI安全 2、安全开发-原生PHP-全局文件&单函数 3、安全开发-原生PHP-流量检测&AI算法 一、演示案例-WEB开发-修复方案-PHP.INI配置 文章参考: https://www.yisu.com/ask/28100386.html https://blog.csdn.net/…...
蓝桥模拟+真题讲解
今天谁一篇文章哈 ! 由于本篇文章有些的题目只有图片,因此还望各位见谅。 目录 第一题 题目解析 代码原理 代码编写 填空技巧---巧用python 第二题 题目解析 编辑 填空技巧---巧用python 第三题 题目链接 题目解析 必备知识 解题技巧 …...
