springboot Filter实现请求响应全链路拦截!完整日志监控方案
一、为什么你需要这个过滤器?
日志痛点:
🚨 请求参数散落在各处?
🚨 响应数据无法统一记录?
🚨 日志与业务代码严重耦合?
解决方案: 一个Filter同时拦截请求和响应,实现日志采集自动化!
二、核心实现:一个Filter搞定双向数据流
1. 过滤器设计亮点
✅ 请求参数捕获:GET/POST参数统一解析
✅ 响应结果截取:支持JSON/XML等文本响应
✅ 零代码侵入:不修改业务代码即可植入监控
✅ JDK1.8完美兼容:无任何新特性依赖
三、完整代码实现
1. 过滤器核心代码(可直接复制)
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;public class RequestResponseLogFilter extends OncePerRequestFilter {@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)throws ServletException, IOException {// 包装请求响应对象ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper(request);ContentCachingResponseWrapper wrappedResponse = new ContentCachingResponseWrapper(response);try {// 执行后续过滤器链filterChain.doFilter(wrappedRequest, wrappedResponse);// 记录日志(核心逻辑)logRequest(wrappedRequest);logResponse(wrappedResponse);} finally {// 必须执行响应回写wrappedResponse.copyBodyToResponse();}}// 请求日志方法private void logRequest(ContentCachingRequestWrapper request) {String method = request.getMethod();String url = request.getRequestURL().toString();String params = getRequestParams(request);System.out.printf("[请求] %s %s | 参数=%s%n", method, url, params);}// 响应日志方法private void logResponse(ContentCachingResponseWrapper response) throws IOException {int status = response.getStatus();String body = getResponseBody(response);System.out.printf("[响应] 状态码=%d | 内容=%s%n", status, body);}// 获取请求参数工具方法private String getRequestParams(ContentCachingRequestWrapper request) {try {if ("GET".equalsIgnoreCase(request.getMethod())) {return request.getQueryString();} else {byte[] body = request.getContentAsByteArray();return new String(body, request.getCharacterEncoding());}} catch (Exception e) {return "[参数解析失败]";}}// 获取响应内容工具方法private String getResponseBody(ContentCachingResponseWrapper response) throws IOException {byte[] content = response.getContentAsByteArray();return new String(content, response.getCharacterEncoding());}@Overridepublic void init(FilterConfig filterConfig) {}@Overridepublic void destroy() {}
}
四、过滤器添加三步走
1. 添加依赖(Maven配置)
xml
<!-- 核心包装类 -->
<dependency><groupId>org.apache.tomcat</groupId><artifactId>tomcat-catalina</artifactId><version>9.0.65</version>
</dependency>
2. web.xml配置(传统项目)
xml
<filter><filter-name>RequestResponseLogFilter</filter-name><filter-class>com.example.RequestResponseLogFilter</filter-class>
</filter><filter-mapping><filter-name>RequestResponseLogFilter</filter-name><url-pattern>/*</url-pattern> <!-- 拦截所有请求 --><dispatcher>REQUEST</dispatcher>
</filter-mapping>
3. Spring Boot集成(新项目推荐)
@Bean
public FilterRegistrationBean<RequestResponseLogFilter> logFilter(){FilterRegistrationBean<RequestResponseLogFilter> registrationBean = new FilterRegistrationBean<>();registrationBean.setFilter(new RequestResponseLogFilter());registrationBean.addUrlPatterns("/*");return registrationBean;
}
五、运行效果演示
[REQUEST] POST http://api/user/login | 参数=username=admin&password=123456 | 时间=Wed Oct 05 14:30:00 CST 2023
[RESPONSE] 状态码=200 | 响应内容={"code":0,"msg":"登录成功"} | 耗时=120ms
六、⚠️ 必须注意的6大事项
内存溢出风险
- 拦截大文件上传时(>1MB)会占用大量内存
- ✅ 解决方案:限制缓存大小
// 在构造方法中设置最大缓存
new ContentCachingRequestWrapper(request, 1024 * 1024); // 1MB
编码兼容性问题
- 请求参数乱码常因缺少编码设置导致
- ✅ 强制设置编码(在Filter头部添加)
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
响应流二次读取
- 原始响应流只能读取一次,必须使用包装类
- ❌ 错误写法:直接使用原始response.getWriter()
敏感信息泄露
- 密码等字段需过滤(正则替换示例)
params.replaceAll("password=\\w+", "password=***");
性能损耗控制
- 高并发场景建议异步记录日志
CompletableFuture.runAsync(() -> log.info(logContent));
HTTPS支持
- 确保Tomcat配置正确:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"SSLEnabled="true" scheme="https" secure="true"/>
七、进阶玩法
🔧 组合使用:
- 搭配Spring AOP实现方法级日志
- 结合Redis实现请求限流
📊 数据分析:
sql
-- 日志分析SQL示例
SELECT request_uri, COUNT(*) as total,AVG(response_time) as avg_time
FROM access_log
WHERE status >= 500
GROUP BY request_uri;
**📌 总结:**一个优秀的Filter就像「数字监控摄像头」,默默记录系统运行轨迹。通过本文的方案,你可以:
1️⃣ 统一管理所有请求响应日志
2️⃣ 零成本实现全链路追踪
3️⃣ 灵活扩展监控维度
公众号:【码农小站】
相关文章:
springboot Filter实现请求响应全链路拦截!完整日志监控方案
一、为什么你需要这个过滤器? 日志痛点: 🚨 请求参数散落在各处? 🚨 响应数据无法统一记录? 🚨 日志与业务代码严重耦合? 解决方案: 一个Filter同时拦截请…...
智能车摄像头开源—9 动态权、模糊PID、速度决策、路径优化
目录 一、前言 二、动态权 1.概述 2.偏差值加动态权 三、模糊PID 四、速度决策 1.曲率计算 2.速度拟合 3.速度控制 五、路径 六、国赛视频 一、前言 在前中期通过识别直道、弯道等元素可进行加减速操作实现速度的控制,可进一步缩减一圈的运行速度ÿ…...
《2025蓝桥杯C++B组:D:产值调整》
**作者的个人gitee** 作者的算法讲解主页▶️ 每日一言:“泪眼问花花不语,乱红飞过秋千去🌸🌸” 题目 二.解题策略 本题比较简单,我的思路是写三个函数分别计算黄金白银铜一次新产值,通过k次循环即可获…...
蓝队技能-Web入侵-入口查杀攻击链
Web攻击事件 分析思路: 1、利用时间节点筛选日志行为 2、利用对漏洞进行筛选日志行为 3、利用后门查杀进行筛选日志行为 4、利用文件修改时间筛选日志行为 Web日志分析 明确存储路径以及查看细节 常见中间件存储路径 IIS、Apache、Tomcat 等中间件的日志存放目…...
Android11车载WiFi热点默认名称及密码配置
一、背景 基于车厂信息安全要求,车载热点默认名称不能使用统一的名称,以及默认密码不能为简单的1~9。 基于旧项目经验,组装工厂自动化测试及客户整车组装的时候均存在多台设备同时打开,亦不太推荐使用统一的热点名称,连接无法区分。 二、需求 根据客户的要求,默认名称…...
对于GAI虚假信息对舆论观察分析
摘要 生成式人工智能(Generative Artificial Intelligence, GAI)的技术革新重构了信息生产机制,但也加剧了虚假信息对舆论生态的异化风险。 关键词:生成式人工智能、虚假信息、舆论异化、智能治理 一、生成式人工智能虚假信息下…...
问题 | 对于初学者来说,esp32和stm32哪个比较适合?
对于初学者选择ESP32还是STM32入门嵌入式开发,需综合考虑学习目标、兴趣方向及未来职业规划。以下是两者的对比分析及建议: 1. 适合初学者的关键因素 ESP32的优势 内置无线通信:集成Wi-Fi和蓝牙功能,无需额外模块即可开发物联网…...
grafana/loki 部署搜集 k8s 集群日志
grafana/loki 和 grafana/loki-stack 的区别 Grafana 提供了多个 Helm Chart 用于在 Kubernetes 集群中部署 Loki 及相关组件,其中主要包括 grafana/loki 和 grafana/loki-stack。它们的主要区别如下: 1.grafana/loki Helm Chart: 专注于 Loki 部署: 该 Chart 专门…...
EN控制同步整流WD1020 ,3.0V-21V 的宽 VIN 输入范围,0.9V-20V 的宽输出电压范围
WD1020 是一款功能强大且性能卓越的电源管理芯片,凭借其独特的特点在众多电子设备领域中展现出广泛的应用前景。以下是对其特点和应用电路的详细阐述: 集成式功率 MOSFET:WD1020 集成了低 RDS(开)功率 MOSFETÿ…...
asm汇编语言源代码之-获取环境变量
提供1个子程序: 1. 读取环境变量 GETENVSTR 具体功能及参数描述如下 GETENVSTR PROC FAR ;IN: DSPSP SEG. ; ES:BX -> ENV VAR NAME ;OUT: DS:DX -> ENV VAR VALUE; IF DX0FFFFH, NOT FOUND ; more source code at http://www.ahjoe.com/source/srcdown.aspPU…...
2025认证杯一阶段各题需要使用的模型或算法(冲刺阶段)
A题(小行星轨迹预测) 问题一:三角测量法、最小二乘法、空间几何算法、最优化方法 问题二:Gauss/Laplace轨道确定方法、差分校正法、数值积分算法(如Runge-Kutta法)、卡尔曼滤波器 B题(谣言在…...
①(PROFINET 转 EtherNet/IP)EtherCAT/Ethernet/IP/Profinet/ModbusTCP协议互转工业串口网关
型号 协议转换通信网关 PROFINET 转 EtherNet/IP MS-GW32 概述 MS-GW32 是 PROFINET 和 EtherNet/IP 协议转换网关,为用户提供两种不同通讯协议的 PLC 进行数据交互的解决方案,可以轻松容易将 EtherNet/IP 网络接入 PROFINET 网络中,方便…...
LeetCode 3272.统计好整数的数目:枚举+排列组合+哈希表
【LetMeFly】3272.统计好整数的数目:枚举排列组合哈希表 力扣题目链接:https://leetcode.cn/problems/find-the-count-of-good-integers/ 给你两个 正 整数 n 和 k 。 如果一个整数 x 满足以下条件,那么它被称为 k 回文 整数 。 x 是一个…...
Linux中的tar -P选项
tar -P选项 Linux中的tar命令可用于文件和目录的归档以及压缩解压缩。而其中的-P选项是什么含义呢?下面我们就来看一看 1、不添加-P选项 对于如下压缩命令: tar -czvf pkg.tar.gz /opt/software执行该命名,控制台首行输出将会提示…...
Linux目录探秘:文件系统的核心架构
引言 Linux文件系统就像一棵精心设计的大树🌳,每个分支都有其特定的用途和规范。与Windows不同,Linux采用单一的目录结构,所有设备、分区和网络资源都挂载在这个统一的目录树下。本文将带你深入探索Linux目录结构的奥秘ÿ…...
国标GB28181视频平台EasyCVR如何搭建汽车修理厂远程视频网络监控方案
一、背景分析 近年我国汽车保有量持续攀升,与之相伴的汽车保养维修需求也逐渐提高。随着社会经济的发展,消费者对汽车维修服务质量的要求越来越高,这使得汽车维修店的安全防范与人员管理问题面临着巨大挑战。 多数汽车维修店分布分散&#…...
python【标准库】multiprocessing
文章目录 介绍多进程Process 创建子进程共享内存数据多进程通信Pool创建子进程多进程案例多进程注意事项介绍 python3.10.17版本multiprocessing 是一个多进程标准模块,使用类似于threading模块的API创建子进程,充分利用多核CPU来并行处理任务。提供本地、远程的并发,高效避…...
南墙WAF非标端口防护实战解析——指定端口安全策略深度剖析
本文系统解析非标端口DDoS攻击防护难点,重点阐述南墙WAF在指定端口防御中的技术突破。通过某金融机构真实攻防案例,结合Gartner最新防御架构模型,揭示如何构建基于智能流量建模的精准防护体系,为金融、政务等关键领域提供可落地的…...
PostIn安装及入门教程
PostIn是一款国产开源免费的接口管理工具,包含项目管理、接口调试、接口文档设计、接口数据MOCK等模块,支持常见的HTTP协议、websocket协议等,支持免登陆本地接口调试,本文将介绍如何快速安装配置及入门使用教程。 1、安装 私有…...
spring cloud微服务API网关详解及各种解决方案详解
微服务API网关详解 1. 核心概念 定义:API网关作为微服务的统一入口,负责请求路由、认证、限流、监控等功能,简化客户端与后端服务的交互。核心功能: 路由与转发:将请求分发到对应服务。协议转换:HTTP/HTTP…...
最新版PhpStorm超详细图文安装教程,带补丁包(2025最新版保姆级教程)
目录 前言 一、PhpStorm最新版下载 二、PhpStorm安装 三、PhpStorm补丁 四、运行PhpStorm 前言 PhpStorm 是 JetBrains 公司推出的 专业 PHP 集成开发环境(IDE),专为提升 PHP 开发效率设计。其核心功能包括智能代码补全、实时语法错误检…...
FileInputStream 详解与记忆方法
FileInputStream 详解与记忆方法 一、FileInputStream 核心概念 FileInputStream 是 Java 中用于从文件读取原始字节的类,继承自 InputStream 抽象类。 1. 核心特点 特性说明继承关系InputStream → FileInputStream数据单位字节(8bit)用…...
【计算机网络】同步操作 vs 异步操作:核心区别与实战场景解析
📌 引言 在网络通信和分布式系统中,**同步(Synchronous)和异步(Asynchronous)**是两种基础却易混淆的操作模式。本文将通过代码示例、生活类比和对比表格,帮你彻底理解它们的区别与应用场景。 1…...
linux kernel arch 目录介绍
一:arch 目录 二:常用arch...
ES6变量声明:let、var、const全面解析
一、引言 ECMAScript 6(简称 ES6)的发布为 JavaScript 带来了许多革命性的变化,其中变量声明方式的更新尤为重要。let、var和const成为开发者日常编码中频繁使用的关键字。 本文将深入解析这三种声明方式的核心特性、区别及最佳实践ÿ…...
Linux 入门八:Linux 多进程
一、概述 1.1 什么是进程? 在 Linux 系统中,进程是程序的一次动态执行过程。程序是静态的可执行文件,而进程是程序运行时的实例,系统会为其分配内存、CPU 时间片等资源。例如,输入 ls 命令时,系统创建进程…...
单调栈 —— 1.基本概念与核心算法
1. 基本概念 1.1 知识预备 在理解单调栈之前,我们需要先掌握两个基础概念:栈(Stack) 和 单调性(Monotonicity)。 什么是栈(Stack) 栈是一种**后进先出(LIFO, Last-In…...
工程师 - 场效应管分类
What Are the Different Types of FETs? Pulse Octopart Staff Jul 31, 2021 Field effect transistors (FETs) are today’s workhorses for digital logic, but they enjoy plenty of applications outside of digital integrated circuits, everything from motor driver…...
用infoNCE微调Embedding模型
infoNCE 代码1:(样本格式为query_n个positive_n个hardnegative) PairwiseModel并不是模型,而是连接model和loss的一个包装类。 PairwiseModel接收两种类型样本 【query pos pair】or【query pos neg triplet】。 CrossEntropy…...
Debezium报错处理系列之第128篇:增量快照报错java.lang.OutOfMemoryError: Java heap space
Debezium报错处理系列之第128篇:增量快照报错java.lang.OutOfMemoryError: Java heap space 一、完整报错二、错误原因三、解决方法Debezium从入门到精通系列之:研究Debezium技术遇到的各种错误解决方法汇总: Debezium从入门到精通系列之:百篇系列文章汇总之研究Debezium技…...
