杰克逊序列化为一个 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: false
和 isAvailable: 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 输出中得到两个变体。
我在将代码从 Java 8 和 Sprint Boot 1.X 迁移到 11 和 2.X 时遇到了一个奇怪的问题。之前,我发现 Jackson 将 private boolean isAvailable
序列化为 available: false
和 isAvailable: 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 输出中得到两个变体。