对之前写的数据脱敏插件进行了修改,使其更加实用很多时候,我们从ORM中查询到的数据还有其他逻辑需要处理,比如根据电话号码查询用户信息。如果脱敏,就没有办法处理这个逻辑。所以脱敏这一步需要在后面做,放在JSON序列化阶段比较合适。今天就来提供此功能吧。Jackson序列化中的脱敏转化过程,其实就是将脱敏post放到JSON序列化过程中。这里我使用Jackson类库。原来Mybatis插件中的脱敏注解是这样的:@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.FIELD)public@interfaceSensitive{SensitiveStrategystrategy();}脱敏策略是这样的:importjava.util.function.Function;/***脱敏策略.**@authorfelord.cn*@since11:25*/publicenumSensitiveStrategy{/***Usernamesensitivestrategy.*/USERNAME(s->s.replaceAll("(\\S)\\S(\\S*)","$1*$2"),/***Idcardsensitivetype.*/ID_CARD(s->s.replaceAll("(\\d{4})\\d{10}(\\w{4})","$1****$2")),/***Phonesensitivetype.*/PHONE(s->s.replaceAll("(\\d{3})\\d{4}(\\d{4})","$1****$2")),/***Addresssensitivetype.*/ADDRESS(s->s.replaceAll("(\\S{3})\\S{2}(\\S*)\\S{2}","$1****$2****");privatefinalFunction脱敏剂;SensitiveStrategy(Functiondesensitizer){this.desensitizer=desensitizer;}publicFunctiondesensitizer(){returndesensitizer;}}我会改造他们,让他们可以脱敏字段属性JSON序列化中的s。自定义脱敏序列化在这里我们首先发现自定义的脱敏序列化总谱:importcom.fasterxml.jackson.core.JsonGenerator;importcom.fasterxml.jackson.databind.BeanProperty;importcom.mappingxml.jackson;importcom.fasterxml.jackson.core.JsonGenerator.fasterxml.jackson.databind.JsonSerializer;importcom.fasterxml.jackson.databind.SerializerProvider;importcom.fasterxml.jackson.databind.ser.ContextualSerializer;importjava.io.IOException;importjava.util.Objects;/***@authorfelord。cn*@since1.0.8.RELEASE*/publicclassSensitiveJsonSerializerextendsJsonSerializerimplementsContextualSerializer{privateSensitiveStrategystrategy;@Overridepublicvoidserialize(Stringvalue,JsonGeneratorgen,SerializerProviderserializers)throwsIOException{gen.writeString(strategy.desensitizer().erypublicizer?@Serializer<值));}>createContextual(SerializerProviderprov,BeanPropertyproperty)throwsJsonMappingException{Sensitiveannotation=property.getAnnotation(Sensitive.class);if(Objects.nonNull(annotation)&&Objects.equals(String.class,property.getType().getRawClass())){this.strategy=annotation.strategy();returnthis;}returnprov.findValueSerializer(property.getType(),property);}}wherecreateContextual该方法用于获取实体类上的@Sensitive注解,并根据条件初始化对应的JsonSerializer对象;顾名思义,serialize方法就是执行脱敏序列化逻辑,将脱敏注解进行转换,然后将@Sensitive转换为序列化上面的自定义JSON,与脱敏策略绑定在一起。这里使用了Jackson的捆绑注解@JacksonAnnotationsInside,它的作用是将多个注解组合在一起;另一个是序列化注解@JsonSerialize,它的作用是声明使用上面我自定义的序列化方法。@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.FIELD)@JacksonAnnotationsInside@JsonSerialize(using=SensitiveJsonSerializer.class)public@interfaceSensitive{SensitiveStrategystrategy();}用这个来完成转换,我们来试试看。我们定义一个需要脱敏的实体类,根据字段上对应的脱敏注解进行标记:/***@authorfelord.cn*@since1.0.8.RELEASE*/@DatapublicclassUser{/***真实姓名*/@Sensitive(strategy=SensitiveStrategy.USERNAME)privateStringrealName;/***地址*/@Sensitive(strategy=SensitiveStrategy.ADDRESS)privateStringaddress;/***电话号码*/@Sensitive(strategy=SensitiveStrategy.PHONE)privateStringphoneNumber;/***身份证号码*/@Sensitive(strategy=SensitiveStrategy.ID_CARD)privateStringidCard;}然后Jackson序列化User实例:Useruser=newUser();user.setRealName("张三丰");user.setPhoneNumber("13333333333");user.setAddress("湖北省十堰市丹江口市武当山");user.setIdCard("4333333333334334333");ObjectMapperobjectMapper=newObjectMapper();Stringjson=objectMapper.writeValueAsString(user);System.out.println(json);可以获取:{"realName":"张*峰","address":"湖北省****市丹江口市吴****","phoneNumber":"133****3333","idCard":"4333****34333"}的效果还是可以的,当然如果能加个开关就更好了,根据不同的场景来决定是否进行脱敏。本文转载自微信公众号“码农小胖哥”,可通过以下二维码关注。转载本文请联系码农小胖公众号。