数据脱敏
hutool
hutool包的DesensitizedUtil
序列化注解,指定序列化器@JsonSerialize
@JacksonAnnotationsInside
:jackson元注解,用于指示Jackson应该使用它所拥有的元注解,在创建“组合注解”时非常有用。
@JsonSerialize
:指定序列化器,可通过继承JsonSerializer.class
以及继承ContextualSerializer
接口自定义序列化策略
ContextualSerializer
:根据文档注释,可得知该接口可为SensitiveJsonSerializer
的扩展,可创建序列化的上下文(SensitiveJsonSerializer)
SensitiveJsonSerializer
:抽象类,继承该类重写方法,即可实现属性的自定义序列化
/**
* 使用该注解的属性,可配置自定义脱敏序列化规则
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@JacksonAnnotationsInside
@JsonSerialize(using = SensitiveJsonSerializer.class)
public @interface Sensitive {
// 脱敏策略
SensitiveStrategy strategy();
}
/**
* 脱敏策略,枚举类,针对不同的数据定制特定的策略
*/
public enum SensitiveStrategy {
/**
* 用户名
*/
USERNAME(s ->s.replaceAll("(\\S)\\S(\\S*)", "$1*$2")),
/**
* 身份证
*/
ID_CARD(s->s.replaceAll("(\\d{4})\\d{10}(\\w{4})", "$1****$2"));
private final Function<String, String> desensitizer;
SensitiveStrategy(Function<String, String> desensitizer){
this.desensitizer = desensitizer;
}
public Function<String, String> desensitizer() {
return desensitizer;
}
}
/**
* ContextualSerializer
* JsonSerializers可以实现的附加接口,以获取回调,该回调可用于创建序列化程序的上下文实例,
* 以用于处理受支持类型的值。这对于可以由注释配置的序列化程序可能很有用,
* 或者应该根据正在序列化的属性类型而具有不同的行为。
*
* JsonSerializer
* 继承该抽象类,重写serialize方法,可自定义属性值序列化
*
*/
public class SensitiveJsonSerializer extends JsonSerializer<String> implements ContextualSerializer {
private SensitiveStrategy strategy;
@Override
public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeString(strategy.desensitizer().apply(value));
}
@Override
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
Sensitive annotation = property.getAnnotation(Sensitive.class);
if (ObjectUtil.isNotNull(annotation) && Objects.equals(String.class,property.getClass())){
this.strategy = annotation.strategy();
return this;
}
return new ToStringSerializer();
}
}