enum的json反序列化问题 415 Unsupported Media Type

简介: enum的反序列过程中如果使用了jackson的注解,很可能会产生一个神奇的bug

enum的反序列化问题 415 Unsupported Media Type

当你的程序在线上出现了error code 415,而本地环境正常的时候,可能就是由于enum的反序列化导致的。

当在enum的反序列化工厂方法上添加了@JsonCreator,且该方法有多个参数,每个参数前都加了@JsonProperty注解,但没有在JsonProperty中显式的指定value为参数名时,就会导致这一问题。

这是一个神奇的bug,在本地测试的时候,不管是用postman还是前端页面发送参数,后端的controller都可以正常的接收,将json的字符串,反序列化为实体类。但是一到了线上,就显示415 content type not supported

{

   "timestamp": "2021-08-13T07:29:27.173+0000",

   "status": 415,

   "error": "Unsupported Media Type",

   "message": "Content type 'application/json;charset=UTF-8' not supported",

   "path": "/ops/submit_inventory_evaluate"

}

经检查restcontroller requestmapping requestbody注解都放在了合适位置,且前端js里content type也采用了application/json,或postman在header里content type也是如此设置。最初怀疑为前端的问题,反复检查无误后,通过postman测试,发现还是415错误,之后将问题定位到了后端

因为本地环境正常,导致测试很困难,只能一点点的排查,发到线上环境再测试,最终将问题锁定到了实体类中一个enum属性。在加了@JsonIgnore注解后,线上环境就可以正常的反序列化了,在查看enum中的toEnum方法时,注意到了上面的@JsonCreator注解,仔细阅读jackson2.9.0中关于该注解的说明。发现该注解当作用于有多个参数的构造或工厂方法上时,每个参数都需要加@JsonProperty,同时在该注解中需要显式的指定value的值,对应哪个属性。除非你使用了支持检测参数名称的扩展模块,因为JDK8之前,默认 JDK 版本无法字节码中存储或检索参数名称。

通过这段话,我开始猜测是本地Oracle的JDK和线上JDK的区别,但是都是JDK8应该都支持这一特性。后面通过搜索这一特性——反射获取方法的参数名称,发现除了要求JDK8及以上,还有一点是编译的时候必须指定编译选项:-parameters,来打开这一特性的支持,默认是关闭的状态。

打开这一特性有三种方法:

  1. 手动命令方式编译:javac -parameters XXX.java


  1. IDE(以Idea为例)编译:Settings -> Build,Execution,Deployment -> Compiler -> Java Compiler


  • Additional command line parameters框中设置为-parameters
  • Override compiler parameters per-module中新增一个module并设置 Compilation options值为-parameters
  • image.png
  1. Maven编译:通过编译插件指定,保证项目迁移的正确性(推荐)

其中第二种方法是IDEA,默认开启的,通过删除这一参数设置,测试发现本地也出现了415错误,最终确认了问题的来源。

目录
相关文章
|
1月前
|
JSON Java Maven
使用Jackson进行 JSON 序列化和反序列化
使用Jackson进行 JSON 序列化和反序列化
23 0
|
1月前
|
存储 JSON 安全
序列化模块pickle和json有什么区别
序列化模块pickle和json有什么区别
18 0
|
2月前
|
JSON 数据格式 C++
[序列化协议] --- JSON
[序列化协议] --- JSON
30 0
|
3月前
|
JSON Java fastjson
Java中的JSON序列化和反序列化
Java中的JSON序列化和反序列化
|
3月前
|
JSON 机器人 数据格式
阿里云RPA支持将序列化的JSON数据作为输入参数传递给机器人应用程序
【1月更文挑战第7天】【1月更文挑战第33篇】阿里云RPA支持将序列化的JSON数据作为输入参数传递给机器人应用程序
206 1
|
4月前
|
XML 存储 JSON
C# 对象存储 (轻松实现序列化 | Xml | Json | 加密 | 压缩 | 注册表 | Redis)
开发时经常会遇到需要保存配置的情况,最常见的实现方式是将对象序列化成Json,再写入文件并保存到本地磁盘。 本文将使用开源库**ApeFree.DataStore**来替换原有的对象存储过程,实现一个可以随意切换存储方式的对象存储方法。 ApeFree.DataStore是一款可配置的对象存储库,支持在不同平台/介质中对内存中的对象进行存储与还原(如本地存储、注册表存储)。支持配置序列化格式(如Json、Xml),支持配置压缩算法(如GZip、Defalte),支持配置加密算法(如AES、RSA)。
67 0
C# 对象存储 (轻松实现序列化 | Xml | Json | 加密 | 压缩 | 注册表 | Redis)
|
4月前
|
XML 存储 JSON
C# | 使用Json序列化对象时忽略只读的属性
将对象序列化成为Json字符串是一个使用频率非常高的功能。Json格式具有很高的可读性,同时相较于XML更节省空间。 在开发过程中经常会遇到需要保存配置的场景,比如将配置信息保存在配置类型的实例中,再将这个对象序列化成为Json字符串并保存。当需要加载配置时,则是读取Json格式的字符串再将其还原成配置对象。在序列化的过程中,默认会将所有公开的属性和字段都序列化进入Json字符串中,这其中也会包含只读的属性或字段,而只读的属性和字段在反序列化的过程中其实是无意义的,也就是说这一部分存储是多余的。 本文将讲解如何在执行Json序列化时,忽略掉那些只读的属性和字段。
53 0
C# | 使用Json序列化对象时忽略只读的属性
|
4月前
|
XML JSON 网络协议
JSON和Protobuf序列化
因为像TCP和UDP这种底层协议只能发送字节流,因此当我们在开发一些远程过程调用(RPC)的程序时,需要将应用层的Java POJO对象序列化成字节流,数据接收端再反序列化成Java POJO对象。序列化一定会设计编码和格式化,目前常见的编码方式有:
|
5月前
|
JSON JavaScript 前端开发
c#JSON序列化&反序列化
JSON(全称为JavaScript ObjectNotation) 是一种轻量级的数据交换格式。它是基于JavaScript语法标准的一个子集。JSON采用完全独立于语言的文本格式,可以很容易在各种网络、平台和程序之间传输。JSON的语法很简单,易于人阅读和编写,同时也易于机器解析和生成。
39 0
|
6月前
|
存储 XML JSON
互联网协议必备:Go语言中JSON的序列化与反序列化
互联网协议必备:Go语言中JSON的序列化与反序列化
68 0