fastJSON反序列化字段順序和序列化忽略null字段問題

一. 描述

1. 在springboot項目中用了 HttpMessageConverters 替換 MappingJackson2HttpMessageConverter

/** jackson替換爲fastjson */
    @Bean
	public HttpMessageConverters fastJsonHttpMessageConverters() {
		FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
		FastJsonConfig fastJsonConfig = new FastJsonConfig();
		fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat,
				SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteMapNullValue,
				SerializerFeature.WriteDateUseDateFormat);
		converter.setSupportedMediaTypes(setMediaType());
		converter.setFastJsonConfig(fastJsonConfig);
		return new HttpMessageConverters(converter);
	}

/**
     * 修改自定義消息轉換器
     * @param converters 消息轉換器列表
     */
    public List<MediaType> setMediaType() {
        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);
       return supportedMediaTypes;

    }

2. 在controller 用 string介紹 json 值

    出現了兩個現象:  1--裏面的值的順序變了, 和json裏面的順序不一致了

                                   2--裏面的null 的值消失

 

二.原因

1. 通過斷點, 發現在FastJsonHttpMessageConverter 中 轉化string的方法

 

其中的反序列化是和 Feature 相關

 

 

2. 在 JSONObject 對象中是包含 null 的值

在用 String 接受時, 調用 JSONObject 的 JSON.toString() 方法, null 就不存在了

序列化的 SerializerFeature 支持

 

三.解決方法

1. 解決序列化的問題, 有兩種

         1. 使用 request 獲取 body, 得到原始的字符串

public String getOriginalBody(HttpServletRequest request, String content) {
		BufferedReader bufferedReader = null;
		try {
			if (request == null) {
				return content;
			} else if (request instanceof RequestWrapper) {
				RequestWrapper requestWrapper = (RequestWrapper) request;
				return requestWrapper.getBody();
			} else {
				StringBuilder builder = new StringBuilder();
				bufferedReader = null;
				InputStream inputStream = request.getInputStream();
				if (inputStream != null) {
					bufferedReader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
					char[] charBuffer = new char[128];
					int bytesRead = -1;
					while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
						builder.append(charBuffer, 0, bytesRead);
					}
				} else {
					builder.append("");
				}
				return builder.toString();
			}
		} catch (Exception e) {
			log.info("getOriginalBody valued, Exception:", e);
		} finally {
			if (bufferedReader != null) {
				try {
					bufferedReader.close();
				} catch (Exception ex) {
					log.info("getOriginalBody bufferedReader, Exception:", ex);
				}
			}
		}
		return content;
	}

          2. 在 FastJsonHttpMessageConverter 中指定 read的策略,反序列化的方式

fastJsonConfig.setFeatures(Feature.OrderedField);

 

2. 解決 string 中不包含 null 的問題

用 JSONObject  代替 String 獲取 @RequestBody 中的內容, JSONObject  含有 null 的值, 不能使用 toString(),  默認不包含 null 的值, 需要自己填充 toJSONString 的  SerializerFeature

	@RequestMapping(value = "/{path}/test", method = { RequestMethod.POST })
	public Object test(@PathVariable("path") String path, @RequestParam("sign") String sign,
			@RequestBody JSONObject json, HttpServletRequest request) {
		String content = JSONObject.toJSONString(json, SerializerFeature.WriteMapNullValue);

		return content;
	}

 

四.fastjson的序列化反序列化

fastjson中SerializerFeature的用法及中文註解  參考:  https://blog.csdn.net/xinyuan_java/article/details/102699378

fastjson中Feature的用法及中文註解  參考:  https://blog.csdn.net/xinyuan_java/article/details/102699418

 

fastjson 提供了很多 對象、字符串 之間的轉化策略, 效率也很高

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章