Java Data Desensitization with Hutool and Custom Jackson Serializer
The article demonstrates how to mask sensitive Java backend data by using Hutool's DesensitizedUtil for common types and a custom @Desensitization annotation with a DesensitizationTypeEnum‑driven Jackson serializer (or Fastjson ValueFilter) to apply flexible masking rules during JSON serialization.
This article explains how to mask sensitive data in Java backend responses using Hutool's DesensitizedUtil and custom Jackson serialization.
Common desensitization methods such as replacement, deletion, reordering, and noise addition are listed, with replacement being the most frequently used.
Using Hutool, you can directly call DesensitizedUtil for types like user ID, Chinese name, ID number, phone, email, and bank card.
For a more flexible solution, a custom annotation @Desensitization is defined, which references a DesensitizationTypeEnum to specify the masking rule.
The annotation is processed by a custom serializer DesensitizationSerialize that implements JsonSerializer and ContextualSerializer . The serializer switches on the enum to apply the appropriate masking logic.
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = DesensitizationSerialize.class)
public @interface Desensitization {
DesensitizationTypeEnum type() default DesensitizationTypeEnum.MY_RULE;
int startInclude() default 0;
int endExclude() default 0;
}The enum can contain custom masking implementations, eliminating the need for switch‑case statements:
public enum DesensitizationTypeEnum {
MY_RULE {
@Override
public String desensitize(String str, Integer start, Integer end) {
return StrUtil.hide(str, start, end);
}
},
USER_ID {
@Override
public String desensitize(String str, Integer start, Integer end) {
return String.valueOf(DesensitizedUtil.userId());
}
},
MOBILE_PHONE {
@Override
public String desensitize(String str, Integer start, Integer end) {
return String.valueOf(DesensitizedUtil.mobilePhone(str));
}
},
EMAIL {
@Override
public String desensitize(String str, Integer start, Integer end) {
return String.valueOf(DesensitizedUtil.email(str));
}
};
public abstract String desensitize(String str, Integer start, Integer end);
}Apply the annotation on model fields:
@Data
public class User {
@Desensitization(type = DesensitizationTypeEnum.MY_RULE, startInclude = 4, endExclude = 7)
private String userid;
@Desensitization(type = DesensitizationTypeEnum.MOBILE_PHONE)
private String phone;
@Desensitization(type = DesensitizationTypeEnum.EMAIL)
private String email;
}When serialized to JSON, the output masks the data, e.g.:
{
"userid": "user***56",
"phone": "181****8155",
"email": "***********@163.com"
}If Fastjson is used instead of Jackson, a custom ValueFilter can be created to perform the same masking.
Java Tech Enthusiast
Sharing computer programming language knowledge, focusing on Java fundamentals, data structures, related tools, Spring Cloud, IntelliJ IDEA... Book giveaways, red‑packet rewards and other perks await!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.