杰克逊序列化为一个 java 变量输出两 json 行

Jackson serialization outputting two json rows for one java variable

我在将代码从 Java 8 和 Sprint Boot 1.X 迁移到 11 和 2.X 时遇到了一个奇怪的问题。之前,我发现 Jackson 将 private boolean isAvailable 序列化为 available: falseisAvailable: false。更令人困惑的是,Lombok 随行,所以我看不到 getter 是否会引起冲突。下面是 Java class 代码:

@Data
public class Availability{

    @JsonProperty("isAvailable")
    private boolean isAvailable;

}

来自 Jackson 对象映射器的结果 JSON 是:

"Availability" : [{
          "isAvailable" : false,
          "available" : false }]

这是 Jackson 2.8。现在使用 Jackson 2.10,我只得到 isAvailable: false 作为 ObjectMapper JSON 中的输出。

"Availability" : [{
          "isAvailable" : false }]

对我来说,它应该只匹配 Java 变量名是有道理的,但遗憾的是合同有两个版本,我不想更改合同。有些正在使用 is,有些则没有。我知道可以使用自定义序列化程序,但不确定如何操作或是否有必要。

是lombok+领域,相互作用

让我们假设一下 class(没有 lombok,或者就此而言,jackson 根本 在这里):

class Example {
    public boolean isAvailable() {
        return true;
    }
}

根据 beanspec,Example class 有一个名为 available 的布尔类型 read-only bean 属性。这是因为任何 returns 布尔值并以 is(然后是大写字母)开头的 no-args 方法都算作访问器, 并获取它的名称,将 is 去掉 .

所以这是从那一端看的。现在让我们从另一端看一下,您写了一个 class,无论出于何种原因,您决定将该字段命名为 isAvailable。真正的问题是:您希望将 'property' 命名为什么(根据 beanspec)?如果真的要叫isAvailable,只有一种方法可以做到:

class Example {
    public boolean isIsAvailable() {
        return true;
    }
}

是的,isIsAvailable。看起来很愚蠢,但是,如果您希望 属性 本身调用 isAvailable,这就是规则的规定。 Lombok 决定(来源:我是核心贡献者)当您在名为 isAvailable.

的字段上粘贴 @Getter 注释时,没有人真的想要一个名为 isIsAvailable 的方法

所以,就杰克逊而言,现在你有一个 class 实际上看起来像:

class Availability {
    @JsonProperty("isAvailable") private boolean isAvailable;

    public boolean isAvailable() { return this.isAvailable; }
}

不使用特定的智能,只是应用文字规则,这意味着杰克逊说:好的,这里有 2 个不同的属性,available(通过调用 isAvailable()) 和 isAvailable 字段。对于 beanspec-style 吸气剂,is/get 被剥离,对于字段它不是,特别是如果你在那里粘贴 @JsonProperty("isAvailable")

这就是这一切发生的背景。

一个解决方案可能是使这个方法:

@JsonProperty("available")
public boolean getAvailable() { return this.available; }

我想这会让你在 JSON 输出中得到两个变体。