当前位置: 首页 > 后端技术 > Java

一个注解就可以实现接口数据脱敏,太强了!

时间:2023-04-01 15:23:01 Java

来源:juejin.cn/post/7110110794188062727愉快的下午,产品小姐姐突然走到我面前,打断了我短暂的钓鱼时间,想和我进行深入的交流。还好我早有准备,没有闪。打开锐思达的点餐页面,暗示没有一杯咖啡解决不了的需求。需求就是一些接口返回的信息。敏感数据必须脱敏。思路1、需要做一个可以配置多种策略的脱敏操作。否则,脱敏操作一项一项进行,重复工作量太大。想了想,定义数据屏蔽注解接口和数据屏蔽逻辑,在返回类上添加需要屏蔽的属性,并指定对应的屏蔽策略操作。2、接下来我只需要截取controller返回的数据,找到带有脱敏注解的属性操作即可。一开始打算用@ControllerAdvice来实现,结果发现需要自己反射类来获取注解。当返回的对象比较复杂,需要递归反映的时候,性能会一下子降低,所以换个思路,我想到了我平时用的@JsonFormat,和我现在的场景很像,通过自定义注解和fieldparsers,字段的自定义解析,tql代码SpringBoot的基础就不介绍了。推荐这个实用教程:https://github.com/javastacks...1.自定义数据注解,配置数据脱敏策略@Target({ElementType.FIELD,ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic@interfaceDataMasking{DataMaskingFuncmaskFunc()defaultDataMaskingFunc.NO_MASK;}2.自定义Serializer,参考jackson的StringSerializer,下面的例子只对String类型进行maskingpublicinterfaceDataMaskingOperation{StringMASK_CHAR="*";Stringmask(Stringcontent,StringmaskChar);}publicenumDataMaskingFunc{/***掩码转换器*/NO_MASK((str,maskChar)->{returnstr;}),ALL_MASK((str,maskChar)->{if(StringUtils.hasLength(str)){StringBuildersb=newStringBuilder();for(inti=0;i{privatefinalDataMaskingOperation操作;publicDataMaskingSerializer(){super(String.class,false);这个。操作=空;}publicDataMaskingSerializer(DataMaskingOperationoperation){super(String.class,false);this.operation=操作;}publicbooleanisEmpty(SerializerProviderprov,Objectvalue){Stringstr=(String)value;返回str.isEmpty();}publicvoidserialize(Objectvalue,JsonGeneratorgen,SerializerProviderprovider)throwsIOException{if(Objects.isNull(operation)){Stringcontent=DataMaskingFunc.ALL_MASK.operation().mask((String)value,null);}gen.writeString(内容);}else{Stringcontent=operation.mask((String)value,null);gen.writeString(内容);}}publicfinalvoidserializeWithType(Objectvalue,JsonGeneratorgen,SerializerProviderprovider,TypeSerializertypeSer)throwsIOException{this.serialize(value,gen,provider);}publicJsonNodegetSchema(SerializerProviderprovider,TypetypeHint){returnthis.createSchemaNode("string",true);}publicvoidacceptJsonFormatVisitor(JsonFormatVisitorWrappervisitor,JavaTypetypeHint)throwsJsonMappingException{this.visitStringFormat(visitor,typeHint);}}3。自定义AnnotationIntrospector,适合我们自定义注解返回对应的Serializer@Slf4jpublicclassDataMaskingAnnotationIntrospectorextendsNopAnnotationIntrospector{@OverridepublicObjectfindSerializer(Annotatedam){DataMaskingannotation=am.getAnnotation(DataMasking.class);}if(annotation!=null){returnnewDataMaskingSerializer(annotation.maskFunc().operation());}返回空值;}}4。覆盖ObjectMapper@Configuration(proxyBeanMethods=false)publicclassDataMaskConfiguration{@Configuration(proxyBeanMethods=false)@ConditionalOnClass({Jackson2ObjectMapperBuilder.class})staticclassJacksonObjectMapperConfiguration{JacksonObjectMapperConfiguration(){}@Bean@PrimaryObjectMapperjacksonObjectMapper(Jackson2ObjectMapperBuilderbuilder){ObjectMapperobjectMapper=builder.createXmlMapper(false).build();AnnotationIntrospectorai=objectMapper.getSerializationConfig().getAnnotation内省器();AnnotationIntrospectornewAi=AnnotationIntrospectorPair.pair(ai,newDataMaskingAnnotationIntrospector());objectMapper.setAnnotationIntrospector(newAi);返回对象映射器;}}}5.带注解的返回对象publicclassUserimplementsSerializable{/***primarykeyID*/privateLongid;/***名称*/@DataMasking(maskFunc=DataMaskingFunc.ALL_MASK)私有字符串名称;/***age*/privateIntegerage;/***email*/@DataMasking(maskFunc=DataMaskingFunc.ALL_MASK)privateStringemail;}近期热点文章推荐:1.1,000+Java面试题及答案(2022最新版)2.厉害了!Java协程来了。.3.SpringBoot2.x教程,太全面了!4.不要用爆破爆满画面,试试装饰者模式,这才是优雅的方式!!5.《Java开发手册(嵩山版)》最新发布,赶快下载吧!感觉不错,别忘了点赞+转发!