利用注解实现接口数据脱敏
首先定义脱敏类型枚举类
public enum SensitiveType {
/**
* 中文名
*/
CHINESE_NAME,
/**
* 手机号
*/
MOBILE_PHONE;
}
定义脱敏注解
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = SensitiveInfoSerialize.class)
public @interface SensitiveInfo {
public SensitiveType value();
}
脱敏序列化类
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 java.io.IOException;
import java.util.Objects;
public class SensitiveInfoSerialize extends JsonSerializer<String> implements ContextualSerializer {
private SensitiveType type;
public SensitiveInfoSerialize() {
}
public SensitiveInfoSerialize(final SensitiveType type) {
this.type = type;
}
@Override
public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
switch (this.type) {
case CHINESE_NAME: {
gen.writeString(SensitiveInfoUtils.chineseName(value));
break;
}
case MOBILE_PHONE: {
gen.writeString(SensitiveInfoUtils.mobilePhone(value));
break;
}
}
}
@Override
public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty property) throws JsonMappingException {
// 为空直接跳过
if (property != null) {
// 非 String 类直接跳过
if (Objects.equals(property.getType().getRawClass(), String.class)) {
SensitiveInfo sensitiveInfo = property.getAnnotation(SensitiveInfo.class);
if (sensitiveInfo == null) {
sensitiveInfo = property.getContextAnnotation(SensitiveInfo.class);
}
// 如果能得到注解,就将注解的 value 传入 SensitiveInfoSerialize
if (sensitiveInfo != null) {
return new SensitiveInfoSerialize(sensitiveInfo.value());
}
}
return serializerProvider.findValueSerializer(property.getType(), property);
}
return serializerProvider.findNullValueSerializer(property);
}
}
脱敏工具类
public class SensitiveInfoUtils {
public static String chineseName(final String fullName) {
if (StringUtils.isBlank(fullName)) {
return "";
}
final String name = StringUtils.left(fullName, 1);
return StringUtils.rightPad(name, StringUtils.length(fullName), "*");
}
public static String mobilePhone(final String phone) {
if (StringUtils.isBlank(phone)) {
return "";
}
return phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
}
}
需要脱敏的实体类
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class User {
private Integer id;
@SensitiveInfo(SensitiveType.CHINESE_NAME)
private String username;
@SensitiveInfo(SensitiveType.MOBILE_PHONE)
private String phone;
private String password;
}
需要脱敏的实体字段,需要脱敏的字段需要添加@SensitiveInfo
注解,并指定脱敏类型
标签: SpringBoot 脱敏