springboot数据动态脱敏

时间:2025-04-16 07:59:54
public class DesensitizeSerializer extends JsonSerializer<String> implements ContextualSerializer { /** * 脱敏规则 */ private DesensitizeRuleEnum rule; private String condition; // SpEL 表达式 private BeanProperty property; // 当前字段属性 @Override public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException { Object currentObject = getCurrentObject(gen); // 获取当前对象 boolean shouldMask = evaluateCondition(currentObject); if (shouldMask) { // 条件满足时脱敏 gen.writeString(rule.function().apply(value)); } else { // 条件不满足时保留原值 gen.writeString(value); } } @Override public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException { //获取对象属性上的自定义注解 CustomSerializer annotation = property.getAnnotation(CustomSerializer.class); if (annotation != null && String.class == property.getType().getRawClass()) { DesensitizeSerializer serializer = new DesensitizeSerializer(); serializer.rule = annotation.function(); // 注入条件表达式 serializer.condition = annotation.condition(); serializer.property = property; return serializer; } return prov.findValueSerializer(property.getType(), property); } private boolean evaluateCondition(Object target) { if (StringUtils.isEmpty(condition)) { return true; // 无条件默认脱敏 } try { // 创建SpEL解析器 ExpressionParser parser = new SpelExpressionParser(); // 设置上下文(target是被序列化的对象) EvaluationContext context = new StandardEvaluationContext(target); // 执行表达式并返回布尔结果 return Boolean.TRUE.equals(parser.parseExpression(condition).getValue(context, Boolean.class)); } catch (Exception e) { log.warn("脱敏条件表达式执行失败: {}", condition, e); return false; // 表达式错误时不脱敏 } } private Object getCurrentObject(JsonGenerator gen) { try { // 获取序列化器上下文中的输出层(底层为 BeanSerializer) Object outputContext = gen.getOutputContext(); if (outputContext instanceof JsonWriteContext) { JsonWriteContext context = (JsonWriteContext) outputContext; // 通过反射获取当前对象实例 Field currentValueField = JsonWriteContext.class.getDeclaredField("_currentValue"); currentValueField.setAccessible(true); return currentValueField.get(context); } } catch (Exception e) { log.warn("无法获取当前对象", e); } return null; } }