Java Jackson在构造函数中使用@JsonProperty名称序列化

Java Jackson在构造函数中使用@JsonProperty名称序列化,java,spring,spring-boot,jackson,Java,Spring,Spring Boot,Jackson,我一直在努力升级我的一个微服务的Spring Boot版本,我偶然发现了一个奇怪的行为。我有这样的课: 公共类过滤器数据{ 私人最终清单装运; 公共过滤器数据(@JsonProperty(“ListShippings”)列出装运){ 这是装运量=装运量; } 公共列表getShippings(){ 退货; } } 在进行升级之前,我的行为是,在反序列化时,JSON对象中使用了名称ListShippings,以映射到Java类的Shippings属性。但是,序列化时,它将使用名称装运编写装运属性

我一直在努力升级我的一个微服务的Spring Boot版本,我偶然发现了一个奇怪的行为。我有这样的课:

公共类过滤器数据{
私人最终清单装运;
公共过滤器数据(@JsonProperty(“ListShippings”)列出装运){
这是装运量=装运量;
}
公共列表getShippings(){
退货;
}
}
在进行升级之前,我的行为是,在反序列化时,JSON对象中使用了名称
ListShippings
,以映射到Java类的
Shippings
属性。但是,序列化时,它将使用名称
装运
编写
装运
属性,而不是
列表装运
。 问题是,现在它在反序列化和序列化时都使用名称
ListShippings
。我不确定这个问题是从什么时候开始出现的,因为我最初的Spring Boot版本是1.5.7,我正在慢慢升级到2.3.4。但我相信这是在2.0.0版之后开始的

我不知道这是由Spring Boot的Jackson自动配置中的某些内部更改引起的,还是由实际Jackson库中的更改引起的,但我很难跟踪这是什么原因以及如何修复它


编辑:我注意到从最新的Spring Boot 1版本(1.5.22)到Spring Boot 2.0.0,Jackson minor版本出现了颠簸(从2.8到2.9)。这可能是问题的原因吗?

弹簧护套1和弹簧护套2之间发生了中断性变化。你已经试过任何方法来修复它了吗?例如,试图将JsonProperty注释移动到字段而不是构造函数?或者使用@JsonCreator


在线资源:

在从Spring Boot 1.5.7.RELEASE切换到2.0.0.RELEASE时,我能够重现这种精确的行为。首先,我添加了父级和spring boot starter web依赖项。然后,我创建了一个简单的
@RestController
,使用您提供的POJO并将
ShipmentData
替换为
String
。当我手动创建Jackson
ObjectMapper
时,我无法在两个版本中重现该问题

最有趣的部分:当您将构造函数的参数名重命名为
以外的名称时,它似乎工作正常。这可能是Jackson或Spring框架中的某个地方的错误,只有当getter与构造函数中的参数名匹配时才会出现

我建议使用
@jsonaas
定义反序列化期间应接受的替代名称:

@JsonCreator
公共过滤器数据(
@JsonProperty(“装运”)
@JsonAlias(“列表装运”)
列出货物清单){
这是装运量=装运量;
}
这样,您就可以使用
列表装运
装运
进行反序列化,而对于序列化,只使用
装运
(由getter定义)


作为参考,2.3.3.1版本的工作实现:

@RestController
公共类筛选器DDataController{
@后映射(“/data”)
公共过滤器数据postFilteredData(@RequestBody FilteredData数据){
返回数据;
}
}
公共类过滤器数据{
私人最终清单装运;
@JsonCreator
公共过滤器数据(
@JsonProperty(“装运”)@JsonAlias(“列表装运”)
列出货物清单){
这是装运量=装运量;
}
公共列表getShippings(){
退货;
}
}
请求:

结果:

{“装运”:[“a”、“b”、“c”]}

我设法找到了问题!这是由名为jackson模块参数名的
spring boot starter web
使用的依赖项引起的。该库提供一个名为
ParameterNamesModule
的Jackson模块,根据Spring Boot的Jackson自动配置,在类路径中找到的任何Jackson模块都会自动导入

中对此库的说明如下所示:

参数名称:支持检测构造函数和工厂方法(“创建者”)参数,而无需使用@JsonProperty注释。提供com.fasterxml.jackson.module.paramnames.ParameterNamesModule

我仍然不能100%确定为什么会产生这样的问题,但通过Maven将其删除解决了这个问题:


org.springframework.boot
SpringBootStarterWeb
com.fasterxml.jackson.module
jackson模块参数名

尝试了两种方法。完全相同的行为
curl -d '{"listShipments":["a","b","c"]}' -H 'Content-Type: application/json' http://localhost:8080/data