responsebodyadvice用于在spring mvc中统一处理响应体,支持响应包装和敏感字段加密;需实现接口并用@controlleradvice注解,通过supports()过滤、beforebodywrite()修改返回值。

在 Spring MVC 中,ResponseBodyAdvice 是一个接口,用于在控制器方法返回值被写入 HTTP 响应体之前,对其进行拦截和修改。它非常适合实现统一响应包装(如封装成 {"code":0,"msg":"ok","data":...})或对敏感字段进行全局加密(如对 data 中的手机号、身份证号等加密)。
实现 ResponseBodyAdvice 的基本步骤
你需要定义一个类,实现 ResponseBodyAdvice 接口,并用 @ControllerAdvice 注解使其生效。Spring 会自动扫描并应用该增强器。
- 泛型参数
T指定你要处理的返回类型(常用Object或具体 DTO 类) -
supports()方法决定是否对该控制器返回值生效(可按注解、类型、包路径等条件过滤) -
beforeBodyWrite()是核心逻辑入口,返回修改后的对象(比如包装后的结果或加密后的数据)
统一响应包装示例
假设你希望所有返回值都包装成 Result<t></t> 结构:
@ControllerAdvice
public class GlobalResponseAdvice implements ResponseBodyAdvice<object> {
@Override
public boolean supports(MethodParameter returnType, Class extends HttpMessageConverter>> converterType) {
// 只对 @RestController 或明确标注 @ResponseBody 的方法生效
return true;
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType,
MediaType selectedContentType,
Class extends HttpMessageConverter>> selectedConverterType,
ServerHttpRequest request,
ServerHttpResponse response) {
// 如果已经是 Result 类型,不重复包装
if (body instanceof Result) {
return body;
}
// 包装为成功响应
return Result.success(body);
}
}</object>
其中 Result.success(data) 返回类似 {"code":200,"msg":"success","data":{...}} 的结构。
对特定字段进行加密(如 data 中的敏感信息)
若需在包装前对 body 中某些字段加密(例如用户手机号),可在 beforeBodyWrite 中做深拷贝+脱敏处理:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 不要直接修改原始对象(可能影响业务逻辑),建议使用反射或 Map/JSON 工具重构
- 推荐用 Jackson 的
ObjectMapper将body转为JsonNode,遍历修改敏感字段,再转回对象或直接返回JsonNode - 也可结合自定义注解(如
@Sensitive)标记需加密字段,在增强器中通过反射识别并替换
简单示例(仅加密字符串类型的手机号):
ObjectMapper mapper = new ObjectMapper();
if (body != null) {
try {
JsonNode node = mapper.valueToTree(body);
if (node.isObject()) {
JsonNode phoneNode = node.get("phone");
if (phoneNode != null && phoneNode.isTextual()) {
String encrypted = encrypt(phoneNode.asText()); // 自定义加密方法
((ObjectNode) node).put("phone", encrypted);
}
}
return mapper.treeToValue(node, returnType.getParameterType());
} catch (Exception e) {
// 处理转换异常,可选择原样返回或抛出
}
}
注意事项与避坑点
避免循环引用和类型不匹配:如果返回类型是 String(如直接返回 JSON 字符串),beforeBodyWrite 中不能返回 POJO,否则 Jackson 会报错。此时应判断 returnType.getParameterType() == String.class 并跳过处理或手动序列化。
慎用静态工具类加密:加密逻辑应尽量无状态、线程安全;若依赖密钥或上下文(如当前用户权限),需从 request 或 SecurityContext 中获取,而非硬编码。
与 @ExceptionHandler 配合使用:异常情况下控制器可能返回 ResponseEntity 或直接 throw 异常,ResponseBodyAdvice 不会处理这些场景,需配合全局异常处理器确保错误响应也符合统一格式。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










