SpringBoot中通过自定义Jackson注解实现接口返回数据脱敏
1、自定义Jackson注解
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 定义一个敏感信息注解,用于标记需要进行脱敏处理的字段。
* 该注解会告知序列化器使用指定的脱敏策略对字段进行处理。
*/
@Retention(RetentionPolicy.RUNTIME) // 注解在运行时有效
@Target(ElementType.FIELD) // 注解适用于字段
@JacksonAnnotationsInside // 将注解应用到字段的内部配置中
@JsonSerialize(using = SensitiveJsonSerializer.class) // 指定使用SensitiveJsonSerializer进行序列化
public @interface Sensitive {
/**
* 脱敏策略枚举,指定对待敏感字段使用的脱敏策略。
*
* @return SensitiveStrategy枚举值,定义了脱敏处理的方式。
*/
SensitiveStrategy strategy();
}
2 指定脱敏策略,这个规则根据业务具体需求去制定
import java.util.function.Function;
/**
* 脱敏策略,枚举类,针对不同的数据定制特定的策略
*/
public enum SensitiveStrategy {
/**
* 用户名脱敏策略
* 将除第一个字符和最后一个字符外的字符替换为星号
*/
USERNAME(s -> s.replaceAll("(\\S)\\S(\\S*)", "$1*$2")),
/**
* 身份证脱敏策略
* 将身份证号码的中间10位数字替换为星号
*/
ID_CARD(s -> s.replaceAll("(\\d{4})\\d{10}(\\w{4})", "$1****$2")),
/**
* 手机号脱敏策略
* 将手机号码中间4位数字替换为星号
*/
PHONE(s -> s.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")),
/**
* 地址脱敏策略
* 将地址中的第四个和倒数第四个字符中间的部分替换为星号
*/
ADDRESS(s -> s.replaceAll("(\\S{3})\\S{2}(\\S*)\\S{2}", "$1****$2****"));
// 脱敏函数,接受一个字符串并返回脱敏后的字符串
private final Function<String, String> desensitizer;
/**
* 构造函数,为每个脱敏策略初始化脱敏函数
* @param desensitizer 脱敏函数
*/
SensitiveStrategy(Function<String, String> desensitizer) {
this.desensitizer = desensitizer;
}
/**
* 获取当前策略的脱敏函数
* @return 脱敏函数
*/
public Function<String, String> desensitizer() {
return desensitizer;
}
}
3 定制JSON序列化实现
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;
/**
* 用于处理敏感信息序列化的自定义JsonSerializer实现。
* 通过应用指定的脱敏策略,将待序列化的字符串进行脱敏处理。
*/
public class SensitiveJsonSerializer extends JsonSerializer<String> implements ContextualSerializer {
private SensitiveStrategy strategy; // 脱敏策略
/**
* 序列化方法,将字符串根据脱敏策略进行处理后,写入JsonGenerator。
*
* @param value 需要序列化的字符串
* @param gen JsonGenerator,用于输出处理后的字符串
* @param serializers SerializerProvider,提供序列化器实例
* @throws IOException 如果在序列化过程中发生IO异常
*/
@Override
public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws
IOException {
gen.writeString(strategy.desensitizer().apply(value));
}
/**
* 根据属性上的Sensitive注解,选择合适的脱敏策略。
*
* @param prov SerializerProvider,提供序列化器实例
* @param property BeanProperty,当前处理的属性
* @return JsonSerializer,根据情况可能返回本实例或寻找合适的值序列化器
* @throws JsonMappingException 如果在处理注解时发生错误
*/
@Override
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws
JsonMappingException {
Sensitive annotation = property.getAnnotation(Sensitive.class);
if (Objects.nonNull(annotation)&&Objects.equals(String.class,
property.getType().getRawClass())) {
this.strategy = annotation.strategy(); // 从注解中获取脱敏策略
return this;
}
return prov.findValueSerializer(property.getType(), property); // 返回默认的值序列化器
}
}
4 对需要脱敏的字段添加注解,并指定脱敏策略,注意:类型需要是String类型,如下
@Sensitive(strategy = SensitiveStrategy.PHONE)
private String phone;
效果如下:
"185****3654"
原文地址:https://blog.csdn.net/qq_41712271/article/details/137817315
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!