自定义注解
package com.yunmeng.iot.common.desensitization.annotation;
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.yunmeng.iot.common.desensitization.enums.SecretStrategy;
import com.yunmeng.iot.common.desensitization.strategy.StringSecretSerializer;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 自定义字符串脱敏注解
*
* @author Linzj
* @date 2023/8/9/009 17:42
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = StringSecretSerializer.class)
public @interface StringSecret {
/**
* 脱敏策略
*
* @return 结果
*/
SecretStrategy strategy();
}
脱敏策略
package com.yunmeng.iot.common.desensitization.enums;
import lombok.Getter;
import java.util.function.Function;
/**
* 脱敏策略,不同数据可选择不同的策略
*
* @author Linzj
* @date 2023/8/9/009 17:57
*/
@Getter
public enum SecretStrategy {
/**
* 用户名脱敏
*/
USERNAME(str -> str.replaceAll("(\\S)\\S(\\S*)", "$1*$2")),
/**
* 身份证脱敏
*/
ID_CARD(str -> str.replaceAll("(\\d{4})\\d{10}(\\w{4})", "$1****$2")),
/**
* 手机号脱敏
*/
PHONE(str -> str.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")),
/**
* 地址脱敏
*/
ADDRESS(str -> str.replaceAll("(\\S{3})\\S{2}(\\S*)\\S{2}", "$1****$2****"));
private final Function<String, String> desensitizer;
SecretStrategy(Function<String, String> desensitizer) {
this.desensitizer = desensitizer;
}
}
序列化器实现
package com.yunmeng.iot.common.desensitization.strategy;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.yunmeng.iot.common.desensitization.annotation.StringSecret;
import com.yunmeng.iot.common.desensitization.enums.SecretStrategy;
import java.io.IOException;
import java.util.Objects;
/**
* 字符串类型序列化器实现
*
* @author Linzj
* @date 2023/8/9/009 17:43
*/
public class StringSecretSerializer extends JsonSerializer<String> implements ContextualSerializer {
private SecretStrategy secretStrategy;
/**
* 步骤一
* 方法来源于ContextualSerializer,获取属性上的注解属性,同时返回一个合适的序列化器
*/
@Override
public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
// 获取自定义注解
StringSecret annotation = beanProperty.getAnnotation(StringSecret.class);
// 注解不为空,且标注的字段为String
if (Objects.nonNull(annotation) && Objects.equals(String.class, beanProperty.getType().getRawClass())) {
this.secretStrategy = annotation.strategy();
// 符合我们自定义情况,返回本序列化器,将顺利进入到该类中的serialize()方法中
return this;
}
// 注解为空,字段不为String,寻找合适的序列化器进行处理
return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
}
/**
* 步骤二
* 方法来源于JsonSerializer<String>:指定返回类型为String类型,serialize()将修改后的数据返回
*/
@Override
public void serialize(String s, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
if (Objects.isNull(secretStrategy)) {
// 定义策略为空,返回原字符串
jsonGenerator.writeString(s);
} else {
// 定义策略不为空,返回策略处理过的字符串
jsonGenerator.writeString(secretStrategy.getDesensitizer().apply(s));
}
}
}
标签:Java,自定义,jackson,str,import,com,annotation,脱敏
From: https://www.cnblogs.com/Linzj5950/p/17778660.html