在开发工作中,有一些用户敏感字段要在后端处理,所以就想在json格式化的时候做处理;我们工程配置的是fastjson来做为json序列化;所以想通过实现fastjson的接口来实现json可配置格式化;
首先想到的坑定是自定义注解了;通过注解来在json格式化的时候;做额外的处理;今天就用自定义注解来实现对手机号的一个脱敏;
首先定义一个注解:
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) public @interface MobileDesensitization { }
然后利用fastjson的提供的拦截接口 ContextValueFilter 进行对字段进行拦截;然后进行数据变更;
注:fastjson提供的filter的类型:
- PropertyPreFilter 根据PropertyName判断是否序列化
- PropertyFilter 根据PropertyName和PropertyValue来判断是否序列化
- NameFilter 修改Key,如果需要修改Key,process返回值则可
- ValueFilter 修改Value
- BeforeFilter 序列化时在最前添加内容
- AfterFilter 序列化时在最后添加内容
以上这些接口都是fastjson提供的一个扩展接口;
我们这里通过最ContextValueFilter 来实现,因为在contextValueFilter中可以很方便的找到这个属性上的注解;上面的那个valueFilter其实也能一样能实现;不过需要自己去获取这些属性的注解;
@Component
public class MobileContextValueFilter implements ContextValueFilter {
private final static Logger logger = LoggerFactory.getLogger(
MobileContextValue
Filter.class);
@Overridepublic Object process(BeanContext context, Object object, String name, Object value) {if(value == null || !(value instanceof String)) {return value;}MobileDesensitization annation = context.getAnnation(MobileDesensitization.class);
if(annation == null) {return value;}String propertyValue = (String) value;if (StringUtils.isBlank(propertyValue)) {return "";}propertyValue = "%s****%s".format(propertyValue.subString(0,4),propertyValue.sub(7));return propertyValue;}}配置fastjson为springmvc工程的json序列化的格式化器:
@Configuration public class MyWebAppConfigurer extends WebMvcConfigurerAdapter { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**"); } @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { FastJsonHttpMessageConverter fastJson = new FastJsonHttpMessageConverter();
//WriteNullStringAsEmpty配置null值转换成空字符串; WriteNonStringValueAsString配置所有的值都加上双引号 fastJson.getFastJsonConfig().setSerializerFeatures(SerializerFeature.WriteNullStringAsEmpty, SerializerFeature.WriteNonStringValueAsString); //下面这个contextType是需要添加;不然后面会报 * 不能匹配所有的contextType类型; List<MediaType> supportedMediaTypes = new ArrayList<>(); supportedMediaTypes.add(MediaType.APPLICATION_JSON); supportedMediaTypes.add(MediaType.APPLICATION_JSON_UTF8); supportedMediaTypes.add(MediaType.APPLICATION_ATOM_XML); supportedMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED); supportedMediaTypes.add(MediaType.APPLICATION_OCTET_STREAM); supportedMediaTypes.add(MediaType.APPLICATION_PDF); supportedMediaTypes.add(MediaType.APPLICATION_RSS_XML); supportedMediaTypes.add(MediaType.APPLICATION_XHTML_XML); supportedMediaTypes.add(MediaType.APPLICATION_XML); supportedMediaTypes.add(MediaType.IMAGE_GIF); supportedMediaTypes.add(MediaType.IMAGE_JPEG); supportedMediaTypes.add(MediaType.IMAGE_PNG); supportedMediaTypes.add(MediaType.TEXT_EVENT_STREAM); supportedMediaTypes.add(MediaType.TEXT_HTML); supportedMediaTypes.add(MediaType.TEXT_MARKDOWN); supportedMediaTypes.add(MediaType.TEXT_PLAIN); supportedMediaTypes.add(MediaType.TEXT_XML); fastJson.setSupportedMediaTypes(supportedMediaTypes); super.configureMessageConverters(converters); }
这样,只要在序列化的字段或者是get方法上;就能够实现脱敏了