SpringBoot不支持HTTP请求头中Accept的自定义值

一、现象

1.Accept值设置为application/json,或不设置值均可以返回正常JSON

application/json
{
  "ResponseStatusObject": {
    "Id": "1",
    "LocalTime": "20191227141606",
    "RequestURL": "/VIID/Subscribes/1",
    "StatusCode": "7",
    "StatusString": "JSON格式无效"
  }
}

2.Accept设置为application/*+json后,返回的JSON中实体字段首字母变成小写

application/*+json
{
  "ResponseStatusObject": {
    "id": "1",
    "statusCode": "7",
    "requestURL": "/VIID/Subscribes/1",
    "statusString": "JSON格式无效",
    "localTime": "20191227141437"
  }
}
二、原因

​ 查看项目中是否配置了消息转换器,比如配置了FastJsonHttpMessageConverter用来替换默认的MappingJackson2HttpMessageConverter。

​ 由于配置FastJsonHttpMessageConverter时只适配了application/json,所以Accept为/或application/json的可以通过此转换器进行转换。如下:

// 添加支持的MediaTypes;不添加时默认为*/*,也就是默认支持全部
List<MediaType> fastMediaTypes = new ArrayList<>();
//这里只支持了application/json
fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
fastJsonHttpMessageConverter.setSupportedMediaTypes(fastMediaTypes);

​ 而application/*+json由于没有适配并且方法上加上了@ResponseBody注解,所有还会走默认的MappingJackson2HttpMessageConverter,所以会出现这种诡异的问题。MappingJackson2HttpMessageConverter对pojo类型序列化的处理转换逻辑如下:

Jackson2在初始化序列器时,对pojo类型对象会收集其属性信息,属性包括成员变量及方法,然后属性名称和处理过后的方法名称做为key保存到一个LinkedHashMap中。收集过程中会调用com.fasterxml.jackson.databind.util.BeanUtil中的legacyManglePropertyName方法用来处理方法名称,它会将get/set方法前缀,即get或set去掉,并将其后面的连续大写字符转换成小写字符返回。例如: getNEWString会转变成newstring返回。你的属性名称如果有这样的"nSmallSellCount",lombok自动生成的get方法就会是这样的"getNSmallSellCount",处理过后就是这样的"nsmallSellCount",这与属性nSmallSellCount并不冲突,可以同时存在于HashMap中。收集完属性信息后,下面的步骤中会删除掉非可见的属性,一般指的是私有成员变量,这时,名称为"nSmallSellCount"的成员变量属性会被删除掉,这样的序列化结果是不会有问题的,但,如果加了@JsonProperty注释,Jackson2会认为这个属性是可见的,不必会删除,这时这两个表示同一个值得属性就会被一同序列化。

三、解决方案(两种选择其一即可)

​ 1.在要转换的POJO类中标注@JsonProperty注解,指定想要转换成的名字。

​ 注意:此种方案有个问题就是如果将注解标注在字段上,那么转成JSON后字段会出现重复问题,具体原因可以参考上面的转换逻辑。将注解标注在get\set方法上面即可。(如果使用了lombok,就只能手动编写get\set方法了)

​ 2.在配置的消息转换器中增加对application/*+json的支持即可。

MediaType mediaType = new MediaType("application", "viid+json", StandardCharsets.UTF_8);
fastMediaTypes.add(mediaType);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容