1. 程式人生 > >springboot工程中用自定義註解的方式json序列化(fastjson)

springboot工程中用自定義註解的方式json序列化(fastjson)

在開發工作中,有一些使用者敏感欄位要在後端處理,所以就想在json格式化的時候做處理;我們工程配置的是fastjson來做為json序列化;所以想通過實現fastjson的介面來實現json可配置格式化;

    首先想到的坑定是自定義註解了;通過註解來在json格式化的時候;做額外的處理;今天就用自定義註解來實現對手機號的一個脫敏;

首先定義一個註解:

@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER}) 
@Retention(RetentionPolicy.RUNTIME)
public @interface MobileDesensitization {

}

然後利用fastjson的提供的攔截介面 ContextValueFilter 進行對欄位進行攔截;然後進行資料變更;

注:fastjson提供的filter的型別:

  1. PropertyPreFilter 根據PropertyName判斷是否序列化
  2. PropertyFilter 根據PropertyName和PropertyValue來判斷是否序列化
  3. NameFilter 修改Key,如果需要修改Key,process返回值則可
  4. ValueFilter 修改Value
  5. BeforeFilter 序列化時在最前新增內容
  6. AfterFilter 序列化時在最後新增內容

以上這些介面都是fastjson提供的一個擴充套件介面;    

我們這裡通過最ContextValueFilter 來實現,因為在contextValueFilter中可以很方便的找到這個屬性上的註解;上面的那個valueFilter其實也能一樣能實現;不過需要自己去獲取這些屬性的註解;

@Component
public class MobileContextValueFilter implements ContextValueFilter {
private final static Logger logger = LoggerFactory.getLogger(MobileContextValueFilter.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方法上;就能夠實現脫敏了