spring boot 中应使用 contentcachingrequestwrapper 包装请求以安全记录接口入参日志,避免重复读取导致 controller 失败;需配置拦截器、注意脱敏与性能限制,并优先考虑 @requestbodyadvice 等更精准方案。

在 Java 的 Spring Boot 项目中,拦截器(HandlerInterceptor)是记录接口入参日志的常用方式之一,但要注意:**原始请求体(如 JSON)只能读取一次**,直接在拦截器里用 request.getInputStream() 会破坏后续 Controller 的正常读取。因此需借助 ContentCachingRequestWrapper 包装请求对象,实现多次读取。
1. 创建可缓存请求的拦截器
继承 HandlerInterceptor,在 preHandle 中包装请求,并提取参数:
- 对
POST/PUT等含 body 的请求,使用ContentCachingRequestWrapper替换原始HttpServletRequest - 通过
getParameterMap()获取 URL 查询参数和表单参数 - 对 JSON 请求体,从缓存中读取字节数组并转为字符串(注意字符编码)
- 建议只记录非敏感字段(如避开 password、token),可用白名单或注解控制
2. 配置拦截器并注册到 WebMvcConfigurer
在配置类中注册拦截器,指定需要拦截的路径(如 /api/**),并排除静态资源和健康检查端点:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 重写
addInterceptors方法,添加自定义拦截器 - 可通过
excludePathPatterns过滤掉/actuator/**、/swagger-ui/**等无需记录的路径 - 注意拦截器执行顺序:多个拦截器按注册顺序依次执行
3. 安全与性能注意事项
记录入参看似简单,但实际需规避几个典型问题:
- 避免重复记录:如果同时用了 AOP 切面和拦截器,可能造成日志重复;建议统一用一种方式
-
防止 OOM:大文件上传或超长 JSON 会撑爆内存,应限制缓存大小(如设置
maxCacheSize=10240) -
脱敏处理:手机号、身份证号等字段建议正则替换(如
"138****1234"),不要硬编码在拦截器里,可抽成工具方法 - 异步线程安全:日志记录尽量用异步(如 Logback 的 AsyncAppender),避免阻塞请求线程
4. 替代方案对比(按推荐度排序)
拦截器适合轻量级、全局统一的日志需求;更复杂的场景可考虑:
-
@ControllerAdvice + @RequestBodyAdvice:精准拦截
@RequestBody参数,天然支持泛型和反序列化前/后处理,推荐用于 JSON 接口 - Filter(如 OncePerRequestFilter):比拦截器更底层,能拦截所有请求(包括静态资源),但无法获取 HandlerMethod,不适合做方法级日志
-
Spring AOP:可基于注解(如
@LogParam)按需开启,灵活性高,但对 Controller 层代理有要求(需确保是 JDK 代理或 CGLIB 正确生效)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










