当两个字段都存在时,如何告诉 Jackson JSON 反序列化器优先选择一个字段而不是另一个字段?

问题描述 投票:0回答:1

我正在编写代码来解析来自服务的 JSON 响应,在该服务中我可以获得两种不同的格式,我想将它们映射到同一类型的对象。这是我的代码的简化示例:

data class MyClass @JsonCreator constructor(
  @JsonProperty("name")
  @JsonAlias("title")
  val name: String
)

以下是一些可以在此设置中正常工作的 JSON blob:

{
  "name": "Mr. Jones"
}

{
  "title": "The Doctor"
}

但是,如果我的 JSON 包含这两个字段,则反序列化器会出错:

{
  "name": "Mr. Jones",
  "title": "The Doctor"
}
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No fallback setter/field defined for creator property 'name' (through reference chain: com.example.MyClass["name"])

我认为这是因为解串器不明白它应该使用这两个字段中的哪一个。如果两者都存在,是否可以指示它应该选择哪一个?我的意图是如果两者都存在,则更喜欢

name
而不是
title
,因此仅当
title
不存在时才应反序列化
name

我目前使用的是 Jackson 2.16.1,并且我的 Maven 项目中有

jackson-core

jackson-annotations
jackson-databind
jackson-dataformat-csv
jackson-module-kotlin

这是我的 ObjectMapper 的主要配置:

val mapper: ObjectMapper = ObjectMapper() .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .configure(DeserializationFeature.FAIL_ON_MISSING_EXTERNAL_TYPE_ID_PROPERTY, false) .configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true) .configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, false) .configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false) .setSerializationInclusion(JsonInclude.Include.NON_NULL) .registerKotlinModule()
我尝试寻找

@JsonAlias

的替代方法(我发现没有任何方法可以做到这一点),并且还尝试设置替代的
@JsonCreator
方法。不幸的是,在实际情况中,我担心有四个字段,而且我不能只为 JSON 中可能出现的每种可能的字段组合编写新的创建者。

@JsonAlias

似乎也没有任何配置选项,而且我还没有在对象映射器的主反序列化器配置中找到一个选项 - 至少是我理解的一个选项。

谢谢!

json jackson alias json-deserialization
1个回答
0
投票
在使用

@JsonAlias

 时,似乎不可能告诉 Jackson 使用一个字段而不是另一个字段。

我使用的 java 记录仅具有 Jackson 用作 JsonCreator 的主记录构造函数(我相信这在 kotlin 数据类中是相同的)。消除 Jackson 错误的一个解决方法是创建实际上不执行任何操作的假 setter。

@JsonProperty("name") private void setName(String ignore) { // dummy setter which makes jackson happy when both values are set } @JsonProperty("title") private void setTitle(String ignore) { // dummy setter which makes jackson happy when both values are set }
注意:这些假 setter 之所以起作用,是因为两个值之一(json 文档中的第一个值)被用作 Creator 属性,并且第二次出现时调用 setter。

需要同时具备这两种方法,以确保 Jackson 可以反序列化 json 文档,无论

name

title
 字段以什么顺序出现。

© www.soinside.com 2019 - 2024. All rights reserved.