fastJSON反序列化字段顺序和序列化忽略null字段问题

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/xinyuan_java/article/details/102699514

一. 描述

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 相关

扫描二维码关注公众号,回复: 7600736 查看本文章

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 提供了很多 对象、字符串 之间的转化策略, 效率也很高

猜你喜欢

转载自blog.csdn.net/xinyuan_java/article/details/102699514