springboot数据动态脱敏

打印 上一主题 下一主题

主题 1761|帖子 1761|积分 5283

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
反射+Jackson数据动态脱敏

我有两个字段,name和type,我想要在type为1对数据脱敏,而其他情况不脱敏:
在网上看到了很多利用Jackson的,但是并没有根据不同情况脱敏,以下是参考了deepseek的实现:
@CustomSerializer注解
  1. @Target(ElementType.FIELD) //表示这个注解只能用在字段上
  2. @Retention(RetentionPolicy.RUNTIME) //注解在运行时保留,可以通过反射读取
  3. @JacksonAnnotationsInside //表示这是一个Jackson组合注解
  4. @JsonSerialize(using = DesensitizeSerializer.class)
  5. public @interface CustomSerializer {
  6.     DesensitizeRuleEnum function();
  7.     String condition() default "";
  8. }
复制代码
DesensitizeSerializer, 根据 SpEL 表达式判定是否脱敏:
  1. public class DesensitizeSerializer extends JsonSerializer<String> implements ContextualSerializer {
  2.     /**
  3.      * 脱敏规则
  4.      */
  5.     private DesensitizeRuleEnum rule;
  6.     private String condition; // SpEL 表达式
  7.     private BeanProperty property; // 当前字段属性
  8.     @Override
  9.     public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
  10.         Object currentObject = getCurrentObject(gen);  // 获取当前对象
  11.         boolean shouldMask = evaluateCondition(currentObject);
  12.         if (shouldMask) {
  13.             // 条件满足时脱敏
  14.             gen.writeString(rule.function().apply(value));
  15.         } else {
  16.             // 条件不满足时保留原值
  17.             gen.writeString(value);
  18.         }
  19.     }
  20.     @Override
  21.     public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
  22.         //获取对象属性上的自定义注解
  23.         CustomSerializer annotation = property.getAnnotation(CustomSerializer.class);
  24.         if (annotation != null && String.class == property.getType().getRawClass()) {
  25.             DesensitizeSerializer serializer = new DesensitizeSerializer();
  26.             serializer.rule = annotation.function();
  27.             // 注入条件表达式
  28.             serializer.condition = annotation.condition();
  29.             serializer.property = property;
  30.             return serializer;
  31.         }
  32.         return prov.findValueSerializer(property.getType(), property);
  33.     }
  34.     private boolean evaluateCondition(Object target) {
  35.         if (StringUtils.isEmpty(condition)) {
  36.             return true; // 无条件默认脱敏
  37.         }
  38.         try {
  39.                 // 创建SpEL解析器
  40.             ExpressionParser parser = new SpelExpressionParser();
  41.             // 设置上下文(target是被序列化的对象)
  42.             EvaluationContext context = new StandardEvaluationContext(target);
  43.             // 执行表达式并返回布尔结果
  44.             return Boolean.TRUE.equals(parser.parseExpression(condition).getValue(context, Boolean.class));
  45.         } catch (Exception e) {
  46.             log.warn("脱敏条件表达式执行失败: {}", condition, e);
  47.             return false; // 表达式错误时不脱敏
  48.         }
  49.     }
  50.     private Object getCurrentObject(JsonGenerator gen) {
  51.         try {
  52.             // 获取序列化器上下文中的输出层(底层为 BeanSerializer)
  53.             Object outputContext = gen.getOutputContext();
  54.             if (outputContext instanceof JsonWriteContext) {
  55.                 JsonWriteContext context = (JsonWriteContext) outputContext;
  56.                 // 通过反射获取当前对象实例
  57.                 Field currentValueField = JsonWriteContext.class.getDeclaredField("_currentValue");
  58.                 currentValueField.setAccessible(true);
  59.                 return currentValueField.get(context);
  60.             }
  61.         } catch (Exception e) {
  62.             log.warn("无法获取当前对象", e);
  63.         }
  64.         return null;
  65.     }
  66. }
复制代码
实体类:
  1. public class Person{
  2.         @CustomSerializer(function = DesensitizeRuleEnum.USERNAME, condition = "type == '1'.toString()")
  3.     @Schema(description = "姓名")
  4.     private String name;
  5.         @Schema(description = "类别,1:xxxx,0:xxxx")
  6.     private String type;
  7. }
复制代码
实现需求,结果涉及公司生产数据,就不放了

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

天津储鑫盛钢材现货供应商

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表