├─ann
└─ DesensitizationAnn
└─processor
└─impl
└─ IdCardProcessor
└─ PhoneProcessor
└─DesensitizationProcessorFactory
└─DesensitizationProcessor
└─DesensitizationSerializer
/**
* 基于Jackson的数据脱敏注解
*
* @author futaosmile@gmail.com
* @date 2022/7/18
* @since 2022/7/18
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Documented
@JsonSerialize(using = DesensitizationSerializer.class)
@JacksonAnnotationsInside
public @interface DesensitizationAnn {
/**
* 数据脱敏处理器
*
* @return 数据脱敏处理器
*/
Class<? extends DesensitizationProcessor> value();
}
/**
* 数据脱敏处理器接口
*
* @author futaosmile@gmail.com
* @date 2022/7/18
* @since 2022/7/18
*/
public interface DesensitizationProcessor {
/**
* 数据脱敏实现
*
* @param target 需要脱敏的数据
* @return 脱敏后的数据
*/
String desensitize(String target);
}
/**
* 18位身份证数据脱敏处理器
*
* @author futaosmile@gmail.com
* @date 2022/7/18
* @since 2022/7/18
*/
public class IdCardProcessor implements DesensitizationProcessor {
private static final String IC_CARD_REG = "(.{6}).*(.{4})";
private static final String REPLACE = "$1********$2";
@Override
public String desensitize(String target) {
if (StringUtils.isBlank(target)) {
return null;
}
return target.replaceAll(IC_CARD_REG, REPLACE);
}
}
/**
* 11位手机号脱敏
*
* @author futaosmile@gmail.com
* @date 2022/7/18
* @since 2022/7/18
*/
public class PhoneProcessor implements DesensitizationProcessor {
private static final String IC_CARD_REG = "(.{3}).*(.{4})";
private static final String REPLACE = "$1****$2";
@Override
public String desensitize(String target) {
if (StringUtils.isBlank(target)) {
return null;
}
return target.replaceAll(IC_CARD_REG, REPLACE);
}
}
- DesensitizationProcessorFactory
/**
* 序列化器工厂类
*
* @author futaosmile@gmail.com
* @date 2022/7/18
* @since 2022/7/18
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@Slf4j
public class DesensitizationProcessorFactory {
private static final Map<String, DesensitizationProcessor> CACHE = new HashMap<>();
public static DesensitizationProcessor getDesensitizationProcessor(Class<? extends DesensitizationProcessor> aClass) {
if (aClass == null) {
return null;
}
String aClassName = aClass.getName();
DesensitizationProcessor desensitizationProcessor = CACHE.get(aClassName);
if (desensitizationProcessor == null) {
try {
DesensitizationProcessor desensitizationProcessorInstance = aClass.newInstance();
CACHE.put(aClassName, desensitizationProcessorInstance);
return desensitizationProcessorInstance;
} catch (InstantiationException | IllegalAccessException e) {
log.error("实例化脱敏处理器失败", e);
return null;
}
} else {
return desensitizationProcessor;
}
}
}
- DesensitizationSerializer
/**
* 数据脱敏序列化器
*
* @author futaosmile@gmail.com
* @date 2022/7/18
* @since 2022/7/18
*/
@Slf4j
public class DesensitizationSerializer extends StdSerializer<String> implements ContextualSerializer {
private transient DesensitizationProcessor desensitizationProcessor;
protected DesensitizationSerializer() {
// 支持的类型
super(String.class);
}
/**
* 创建上下文信息
*
* @param prov Serializer provider to use for accessing config, other serializers
* @param property Method or field that represents the property
* (and is used to access value to serialize).
* Should be available; but there may be cases where caller can not provide it and
* null is passed instead (in which case impls usually pass 'this' serializer as is)
* @return
*/
@Override
public JsonSerializer<String> createContextual(SerializerProvider prov, BeanProperty property) {
DesensitizationAnn desensitizationAnn = property.getAnnotation(DesensitizationAnn.class);
if (desensitizationAnn != null) {
Class<? extends DesensitizationProcessor> value = desensitizationAnn.value();
DesensitizationProcessor curDesensitizationProcessor = DesensitizationProcessorFactory.getDesensitizationProcessor(value);
log.debug("cur processor is:{}", curDesensitizationProcessor);
if (curDesensitizationProcessor == null) {
log.error("无法获取{}对应的processor实例", value);
} else {
this.desensitizationProcessor = curDesensitizationProcessor;
}
}
return this;
}
@Override
public void serialize(String value, JsonGenerator gen, SerializerProvider provider) throws IOException {
log.debug("cur obj is:{}", this);
if (this.desensitizationProcessor != null) {
try {
gen.writeObject(desensitizationProcessor.desensitize(value));
} catch (Exception e) {
log.error("自定义脱敏处理器数据脱敏失败", e);
gen.writeObject(value);
}
} else {
gen.writeObject(value);
}
}
}