全局异常处理中请求参数脱敏的核心是用ContentCachingRequestWrapper缓存请求体,按GET/POST区分处理:GET用getParameterMap脱敏key值,JSON请求用ObjectMapper递归脱敏敏感字段,结合白名单匹配并记录结构化日志。

在全局异常处理中对请求参数进行脱敏记录,核心思路是:在捕获异常前先获取并处理原始请求数据,过滤敏感字段(如密码、身份证号、手机号等),再将脱敏后的参数存入日志或异常上下文中。
获取请求参数并识别敏感字段
Spring Boot 中常用 @ControllerAdvice + @ExceptionHandler 做全局异常处理。但默认情况下,HttpServletRequest 的参数只能读取一次(因为 InputStream 只能消费一次),所以需借助 ContentCachingRequestWrapper 包装请求,缓存请求体内容。
- 对于
GET请求:参数在 URL 查询字符串中,可通过request.getParameterMap()获取,再按 key 脱敏(如"password","idCard") - 对于
POST/PUT请求(JSON):需读取request.getInputStream(),解析为 Map 或 JSON 对象,递归遍历字段,匹配敏感关键词并替换(如密码替换成"***") - 建议维护一个敏感字段白名单(如
Set.of("password", "pwd", "idCard", "phone", "bankCard")),避免硬编码
使用 RequestWrapper 实现可重复读取
自定义过滤器(如 ContentCachingRequestFilter),将原始 HttpServletRequest 包装为 ContentCachingRequestWrapper,确保在异常处理器中仍能读取请求体。
- 在
doFilter中执行new ContentCachingRequestWrapper(request) - 注意:该 wrapper 默认只缓存前 10KB 内容,如需支持大请求体,需重写或配置
spring.http.log-request-details=true(仅开发环境) - 在异常处理器中通过
WebUtils.getNativeRequest(request, ContentCachingRequestWrapper.class)获取包装对象
在异常处理器中脱敏并记录
在 @ExceptionHandler 方法内,结合请求方式和内容类型,统一提取并脱敏参数:
立即学习“Java免费学习笔记(深入)”;
- 判断
request.getMethod()和contentType(如application/json或application/x-www-form-urlencoded) - 对 JSON 请求:用
ObjectMapper解析为JsonNode,递归遍历所有字段,命中敏感 key 则设为"***";再转回字符串用于日志 - 对表单请求:调用
request.getParameterMap(),遍历 key,敏感 key 对应的 value 替换为"***" - 记录日志时,推荐使用结构化日志(如 Logback 的
LoggingEvent或 SLF4J MDC),把脱敏后参数放入MDC.put("safeParams", jsonStr),便于 ELK 检索
避免常见陷阱
脱敏不是简单“替换字符串”,需兼顾安全与可用性:
- 不要在脱敏后修改原始请求对象(如
setParameter不生效),只做日志用途的副本处理 - 避免正则全量模糊匹配(如匹配
"pass.*"可能误伤"passport"),优先用精确 key 匹配 + 大小写不敏感 - 文件上传请求(
multipart/form-data)中,非文件字段可按表单处理,文件字段跳过解析,仅记录文件名和大小 - 若使用 Spring Security,注意异常可能发生在 Filter 链早期(如认证失败),此时请求可能尚未进入 MVC,需在更前置的 Filter 中做脱敏准备


















