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…...
Debian二次开发一体化工作站:提升科研效率的智能工具
在科研领域,数据处理是实验成功的关键环节之一。随着实验数据的复杂性和规模不断增加,传统的数据处理方法已经难以满足科研人员的需求。这时,一体化工作站应运而生,成为科研实验数据处理的 “智能大脑”。 一体化工作站ÿ…...
swift-5-汇编分析闭包本质
一、枚举、结构体、类都定义方法 方法占用对象的内存么? 不占用 方法的本质就是函数 方法、函数都存放在代码段,因为方法都是公共的,不管 对象一还是对对象二调用都是一样的,所以放在代码段,但是每个对象的成员不一样所…...
Linux安装升级docker
Linux 安装升级docker Linux 安装升级docker背景升级停止docker服务备份原docker数据目录移除旧版本docker安装docker ce恢复数据目录启动docker参考 安装找到docker官网找到docker文档删除旧版本docker配置docker yum源参考官网继续安装docker设置开机自启配置加速测试 Linux …...
小程序事件系统 —— 33 事件传参 - data-*自定义数据
事件传参:在触发事件时,将一些数据作为参数传递给事件处理函数的过程,就是事件传参; 在微信小程序中,我们经常会在组件上添加一些自定义数据,然后在事件处理函数中获取这些自定义数据,从而完成…...
推荐一些免费开源支持Vue3甘特图组件
文章目录 前言一、dhtmlxGantt二、frappe-gantt三、vue-ganttastic四、gantt-elastic五、v-gantt六、vue-gantt-schedule-timeline-calendar七、vue-gantt八、总结 前言 在现代项目管理和任务调度中,甘特图是一种非常实用的工具。它能够直观地展示任务的时间安排、…...
Dify 本地部署教程
目录 一、下载安装包 二、修改配置 三、启动容器 四、访问 Dify 五、总结 本篇文章主要记录 Dify 本地部署过程,有问题欢迎交流~ 一、下载安装包 从 Github 仓库下载最新稳定版软件包,点击下载~,当然也可以克隆仓库或者从仓库里直接下…...
nlp培训重点-5
1. LoRA微调 loader: # -*- coding: utf-8 -*-import json import re import os import torch import numpy as np from torch.utils.data import Dataset, DataLoader from transformers import BertTokenizer """ 数据加载 """cl…...
XWiki使用war部署在tomcat9
xwiki部署 官方文档,比较详细。 https://www.xwiki.org/xwiki/bin/view/Documentation/AdminGuide/Installation/InstallationWAR/ xwiki是基于java的开源知识库,可以替代Confluence。有多种部署方式,本文使用war方式部署在tomca下&#x…...
CTA策略【量化理论】
CTA策略演变史 全称:Commodity Trading Advisor (商品交易顾问) CTA最开始是指通过为客户提供期权、期货方面的交易建议,或者直接通过受管理的期货账户参与实际交易,来获得收益的机构或个人。 随着市场的发展&#…...
旋转编码器原理与应用详解:从结构到实战 | 零基础入门STM32第四十七步
主题内容教学目的/扩展视频旋转编码器电路原理,跳线设置,结构分析。驱动程序与调用。熟悉电路和驱动程序。 师从洋桃电子,杜洋老师 📑文章目录 一、旋转编码器是什么?二、内部结构揭秘2.1 机械组件解剖2.2 核心部件说明…...
计算机视觉cv2入门之图像的读取,显示,与保存
在计算机视觉领域,Python的cv2库是一个不可或缺的工具,它提供了丰富的图像处理功能。作为OpenCV的Python接口,cv2使得图像处理的实现变得简单而高效。 示例图片 目录 opencv获取方式 图像基本知识 颜色空间 RGB HSV 图像格式 BMP格式 …...
基于Canvas和和原生JS实现俄罗斯方块小游戏
这里是一个完整的H5俄罗斯方块游戏,使用了 HTML CSS JavaScript (原生) 实现,支持基本的俄罗斯方块玩法,如: ✅ 方块自动下落 ✅ 方向键控制移动、旋转、加速下落 ✅ 方块堆叠、消行 ✅ 计分系统 在 canvas 上绘制游戏&#x…...
阿里云 QwQ-32B 模型调研文档
阿里云 QwQ-32B 模型调研文档 ——技术解析、部署实践与微调指南 一、模型概述 QwQ-32B 是阿里云开源的轻量化大语言模型,以 320 亿参数 实现与 DeepSeek-R1(6710 亿参数)相当的推理性能。其核心优势包括: 参数效率:1/20 参数量达成竞品性能,显存需求降低 70%部署灵活性…...
【玩转23种Java设计模式】结构型模式篇:组合模式
软件设计模式(Design pattern),又称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。 汇总目录链接&…...
Eolink:专为开发者设计的API协作平台
Eolink Apikit 是一款集 API 设计、管理、自动化测试、Mock 和异常监控于一体的全生命周期智能协作平台,旨在提升 API 研发和管理的效率。以下是对其功能和特点的详细介绍: 核心功能: API 设计与文档管理:Apikit 提供了强大的 API…...
【Python】为什么要写__init__.py
文章目录 PackageA(__init__特性)应该往__init__.py里放什么东西?1、包的初始化2、管理包的公共接口3、包的信息 正常我们直接导入就可以执行,但是在package的时候,有一种__init__.py的特殊存在 引入moduleA.py,执行main.py&…...
golang 从零单排 (一) 安装环境
1.下载安装 打开网址The Go Programming Language 直接点击下载go1.24.1.windows-amd64.msi 下载完成 直接双击下一步 下一步 安装完成 环境变量自动设置不必配置 2.验证 win r 输入cmd 打开命令行 输入go version...
30-判断子序列
给定字符串 s 和 t ,判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列&#…...
AI 驱动的软件测试革命:从自动化到智能化的进阶之路
🚀引言:软件测试的智能化转型浪潮 在数字化转型加速的今天,软件产品的迭代速度与复杂度呈指数级增长。传统软件测试依赖人工编写用例、执行测试的模式,已难以应对快速交付与高质量要求的双重挑战。人工智能技术的突破为测试领域注…...
深度相机进行目标物体的空间姿态(位姿)估计
利用深度相机(如Kinect、Intel Realsense、Zed相机等)进行目标物体的空间姿态(位姿)估计,通常结合了3D点云处理、目标识别和位姿优化算法。以下是完整的实现流程、算法选择及注意事项: 一、实现流程 1. 目…...
3月8日实验
拓扑: 需求: 1.学校内部的HTTP客户端可以正常通过域名www.baidu.com访问到白度网络中的HTTP服务器 2.学校网络内部网段基于192.168.1.0/24划分,PC1可以正常访问3.3.3.0/24网段,但是PC2不允许 3.学校内部路由使用静态路由&#…...
GO语言学习笔记
一、viper笔记【七米】 https://liwenzhou.com/posts/Go/viper/ 二、优雅关机和平滑重启 https://liwenzhou.com/posts/Go/graceful-shutdown/ 三、gin使用zap https://liwenzhou.com/posts/Go/zap-in-gin/ 四、flag 用于命令行传参 https://liwenzhou.com/posts/Go/flag/ 五、…...
Autosar技术栈总目录
总目录 Autosar架构理解Autosar Mcal配置开发(TC3xx系列 基于EB)Autosar Mcal配置开发(S32K3xx系列 基于EB)Autosar BSW服务开发(基于Davinci CFG &Dev)Makefile编译自动化脚本 持续更新中… Autosar架…...
开发指南107-谷歌内核浏览器滚动条设置
平台上统一制定了滚动条样式(仅限于webkit内核):/* ------美化谷歌浏览器滚动条 开始-----------*/ ::-webkit-scrollbar{width:12px;height:12px;background-color: #E1E1E1;} ::-webkit-scrollbar-button:single-button { background-color:#E1E1E1; display: …...
25年携程校招社招求职能力北森测评材料计算部分:备考要点与误区解析
在求职过程中,能力测评是筛选候选人的重要环节之一。对于携程这样的知名企业,其能力测评中的材料计算部分尤为关键。许多求职者在备考时容易陷入误区,导致在考试中表现不佳。本文将深入解析材料计算部分的实际考察方向,并提供针对…...
Linux系统编程--线程同步
目录 一、前言 二、线程饥饿 三、线程同步 四、条件变量 1、cond 2、条件变量的使用 五、条件变量与互斥锁 一、前言 上篇文章我们讲解了线程互斥的概念,为了防止多个线程同时访问一份临界资源而出问题,我们引入了线程互斥,线程互斥其实…...
李沐《动手学深度学习》——14.9. 用于预训练BERT的数据集——wiki数据集问题以及存在的其他问题
问题1:出现"file is not a zip file" 原因是链接已经失效。 解决方法:打开下面链接自行下载,需要魔法。下载完解压到特定位置。 下载链接:项目首页 - Wikitext-2-v1数据包下载:Wikitext-2-v1 数据包下载本仓库提供了一…...
【英伟达AI论文】多模态大型语言模型的高效长视频理解
摘要:近年来,基于视频的多模态大型语言模型(Video-LLMs)通过将视频处理为图像帧序列,显著提升了视频理解能力。然而,许多现有方法在视觉主干网络中独立处理各帧,缺乏显式的时序建模,…...
深入理解 DOM 元素
深入理解 DOM 元素:构建动态网页的基石 在网页开发的世界里,DOM(Document Object Model,文档对象模型)元素宛如一座桥梁,连接着静态的 HTML 结构与动态的 JavaScript 交互逻辑。它让原本呆板的网页变得鲜活…...
linux如何判断进程对磁盘是随机写入还是顺序写入?
模拟工具&性能测试工具:fio fio参数说明: filename/dev/sdb1:测试文件名称,通常选择需要测试的盘的data目录。 direct1:是否使用directIO,测试过程绕过OS自带的buffer,使测试磁盘的结果更真…...
实现静态网络爬虫(入门篇)
一、了解基本概念以及信息 1.什么是爬虫 爬虫是一段自动抓取互联网信息的程序,可以从一个URL出发,访问它所关联的URL,提取我们所需要的数据。也就是说爬虫是自动访问互联网并提取数据的程序。 它可以将互联网上的数据为我所用,…...
[Web]get请求和post请求
Get get请求的特点是: 1.所有的参数都通过URL进行传递。其中传输的参数的书写的格式为?key1value1&key2value2。具体示例:https://example.com/search?qapple&limit10。访问的时候,先写/xxx,确定本次请求要访问的资源u…...
【落羽的落羽 C++】C++入门基础:引用,内联,nullptr
文章目录 一、引用1. 引用的概念2. 引用的特点3. 引用的使用4. const引用5. 引用和指针 二、inline内联三、nullptr 一、引用 1. 引用的概念 引用是C中的一个较为重要的概念。它是给已存在变量取的“别名”,编译器不会为引用变量开辟内存空间,它和它引…...
RabbitMQ应用问题大全(精心整理版)
前言 其实这部分知识我是整理在语雀上了,这里是直接复制粘贴过来的。不是很好阅读,可以直接点下方链接去语雀看,那个看的会舒服很多。 https://www.yuque.com/g/ngioig/upbg6b/fkarhyo8fpgrtyq8/collaborator/join?tokenGvlO0di8KaIfO8aF&am…...
【人工智能】卷积神经网络的奥秘:深度学习的视觉革命
卷积神经网络(CNN)是深度学习中处理图像、视频等高维数据的主流模型,因其局部特征提取和参数共享特性而效率高且效果优异。本文深入探讨了CNN的理论基础,包括卷积操作、池化层、激活函数和全连接层的数学原理,并通过LaTeX公式推导其前向传播和反向传播过程。接着,我们提供…...
掌握MiniQMT:程序化下单与撤单的高效实现
掌握MiniQMT:程序化下单与撤单的高效实现 🚀量化软件开通 🚀量化实战教程 在量化交易领域,程序化下单与撤单是实现自动化交易策略的关键环节。通过MiniQMT平台,我们可以高效地执行这些操作,从而快速响应…...
【高级篇】大疆Pocket 3加ENC编码器实现无线RTMP转HDMI进导播台
【高级篇】大疆Pocket 3加ENC编码器实现无线RTMP转HDMI进导播台 文章目录 准备工作连接设备RTMP概念ENCSHV2推流地址设置大疆Pocket 3直播设置总结 老铁们好! 很久没写软文了,今天给大家带了一个干货,如上图,大疆Pocket 3加ENC编…...
Nacos学习笔记-占位符读取其他命名空间内容
Nacos当前命名空间下的配置文件需要跨命名空间读取其他配置文件的内容。可以先通过Nacos提供的API接口获取配置文件内容,然后解析数据将其放入环境的PropertySource中。 相关依赖包 <!-- Nacos依赖包 --> <dependency><groupId>com.alibaba.clo…...
每天五分钟深度学习框架PyTorch:使用残差块快速搭建ResNet网络
本文重点 前面我们使用pytorch搭建了残差块,本文我们更进一步,我们使用残差块搭建ResNet网络,当学会如何搭建残差块之后,搭建ResNet就会非常简单了,因为ResNet就是由多个残差块组成的。 残差块 残差块我们前面已经介…...
python操作java文件的一种方法
对于python操作java代码的场景来说,比较多的可能就是涉及加密的场景,尤其涉及到登录的场景,对于输入的账号密码可能会涉及到加密,如果开发告诉我们如何加密,那么,OK,我们可以直接通过代码去实现…...
自然语言处理:最大期望值算法
介绍 大家好,博主又来给大家分享知识了,今天给大家分享的内容是自然语言处理中的最大期望值算法。那么什么是最大期望值算法呢? 最大期望值算法,英文简称为EM算法,它的核心思想非常巧妙。它把求解模型参数的过程分成…...
leetcode-sql数据库面试题冲刺(高频SQL五十题)
题目: 197.上升的温度 表: Weather ---------------------- | Column Name | Type | ---------------------- | id | int | | recordDate | date | | temperature | int | ---------------------- id 是该表具有唯一值的列。 没有具有相同 recordDate …...
开发者社区测试报告(功能测试+性能测试)
功能测试 测试相关用例 开发者社区功能背景 在当今数字化时代,编程已经成为一项核心技能,越来越多的人开始学习编程,以适应快速变化的科技 环境。基于这一需求,我设计开发了一个类似博客的论坛系统,专注于方便程序员…...
环形链表问题的探究与代码实现
在数据结构与算法的学习中,环形链表是一个经典的问题。它不仅考察对链表这种数据结构的理解,还涉及到指针操作和逻辑推理。本文将结合代码和图文,深入分析如何判断链表中是否有环以及如何找到环的入口点。 目录 一、判断链表中是否有环 …...
【C++】vector(下):vector类的模拟实现(含迭代器失效问题)
文章目录 前言一、vector类的常用接口的模拟实现1.头文件(my vector.h)整体框架2.模拟实现vector类对象的常见构造3.模拟实现vector iterator4.模拟实现vector类对象的容量操作5.模拟实现vector类对象的访问6.模拟实现vector类对象的修改操作 二、vector…...
NLTK和jieba
NLTK与jieba概述 自然语言处理(NLP)领域是计算机科学领域与人工智能领域中的一个重要方向,主要研究方向是实现人与计算机之间用自然语言进行有效通信的各种理论和方法。 在自然语言处理领域中,文本类型的数据占据着很大的市场&a…...
Java后端高频面经——计算机网络
TCP/IP四层模型?输入一个网址后发生了什么,以百度为例?(美团) (1)四层模型 应用层:支持 HTTP、SMTP 等最终用户进程传输层:处理主机到主机的通信(TCP、UDP&am…...
CSDN博客:Markdown编辑语法教程总结教程(中)
❤个人主页:折枝寄北的博客 Markdown编辑语法教程总结 前言1. 列表1.1 无序列表1.2 有序列表1.3 待办事项列表1.4 自定义列表 2. 图片2.1 直接插入图片2.2 插入带尺寸的图片2.3 插入宽度确定,高度等比例的图片2.4 插入高度确定宽度等比例的图片2.5 插入居…...
Springboot redis bitMap实现用户签到以及统计,保姆级教程
项目架构,这是作为demo展示使用: Redis config: package com.zy.config;import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.Ob…...