java中注解本身不执行脱敏,需结合反射与aop或jackson序列化扩展实现:先定义@sensitive注解和sensitivetype枚举标记字段,再通过sensitiveutils提供手机号、身份证等脱敏规则,最后在json序列化时用自定义sensitivejsonserializer或aop切面统一处理。

Java 中注解本身不能直接实现敏感数据脱敏,它只是元数据标记;真正起作用的是结合反射 + AOP(如 Spring AOP 或 AspectJ)或序列化扩展(如 Jackson 的自定义序列化器),在运行时读取注解并执行脱敏逻辑。
定义脱敏注解
先创建一个自定义注解,用于标记需要脱敏的字段:
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Sensitive {
SensitiveType value() default SensitiveType.ID_CARD;
}
再定义脱敏类型枚举:
public enum SensitiveType {
PHONE, ID_CARD, EMAIL, BANK_CARD, NAME
}
编写脱敏工具类
提供通用脱敏规则,例如手机号中间四位替换成 ****,身份证保留前3位和后4位等:
- PHONE → 138****1234
- ID_CARD → 110****1234
- EMAIL → u***@example.com
- NAME → 张*、李**(根据长度动态处理)
工具类示例:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
public class SensitiveUtils {
public static String desensitize(String original, SensitiveType type) {
if (original == null || original.isEmpty()) return original;
return switch (type) {
case PHONE -> maskPhone(original);
case ID_CARD -> maskIdCard(original);
case EMAIL -> maskEmail(original);
case NAME -> maskName(original);
default -> original;
};
}
// 具体 maskXXX 方法略(正则或字符串截取实现)
}
在 JSON 序列化时自动脱敏(推荐,侵入小)
使用 Jackson,通过自定义 JsonSerializer,在序列化对象字段时检查 @Sensitive 注解:
public class SensitiveJsonSerializer extends JsonSerializer<string> {
@Override
public void serialize(String value, JsonGenerator gen, SerializerProvider serializers)
throws IOException {
// 获取当前字段的注解(需配合 ContextualSerializer 获取 field)
Sensitive sensitive = getCurrentFieldAnnotation();
if (sensitive != null && value != null) {
gen.writeString(SensitiveUtils.desensitize(value, sensitive.value()));
} else {
gen.writeString(value);
}
}
}</string>
然后在实体字段上使用:
public class User {
private String name;
@Sensitive(SensitiveType.PHONE)
private String phone;
@Sensitive(SensitiveType.ID_CARD)
private String idCard;
// getter/setter...
}
最后注册该序列化器(Spring Boot 中可通过 SimpleModule 注册)。
用 AOP 在 Controller 返回前统一处理(适合 DTO 返回场景)
定义切面,拦截返回值为对象或集合的方法,递归扫描字段,对带 @Sensitive 的 String 字段替换值:
- 使用
@Around切 Controller 方法 - 用反射遍历返回对象所有字段(含嵌套对象、List、Map)
- 遇到
@Sensitive字段且类型为 String,调用脱敏工具处理 - 注意跳过 final、static、null 值,避免修改原始对象(建议深拷贝或构造新对象)
这种方式灵活但性能开销略高,适合统一出口控制。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










