具有短名称的字段的默认 Jackson 命名策略
default Jackson naming strategy for fields with short names
我使用 Jackson 很多年了,我不确定我是否遇到过这个问题。
在 Spring Boot 2.5.5 项目中使用 Jackson 2.12.5,我有一个需要序列化的对象。我对其他领域没有问题,但是这两个领域给我带来了问题:
@Jacksonized
@Builder
@Getter
public class ComputationResult {
private final String pId;
private final String cId;
... other fields ignored
}
如您所见,我也在使用 Lombok 注释。当“delombokized”时,吸气剂是:
public String getPId() {
return this.pId;
}
public String getCId() {
return this.cId;
}
序列化 POJO 时,我希望字段名称为“pId”和“cId”,但它们不是:我得到“pid”和“cid”,均为小写。我对其他领域没有问题,尊重案例。
这给我带来了一个问题,因为我需要序列化然后反序列化 POJO,反序列化失败是因为它无法将“cid”json 字段映射到“cId”java 字段。
有多种解决方法(我在现场使用 @JsonAlias("cid")
以允许反序列化),但我很困惑:这是杰克逊的预期行为吗?它会根据长度对字符串字段进行不同的处理吗?还是我不知道的 java beans 约定?
是否可以在 objectMapper 中设置 属性 来“修复”该行为,而无需实现我自己的 com.fasterxml.jackson.databind.PropertyNamingStrategy
?
问题似乎是由 属性 名称开头只有一个小写字符时 JavaBeans 方法如何生成引起的。你可能会对 getpId
and getcId
are indeed correctly named 和我一样感到惊讶。
简而言之,pId
正确地导致了 getter getpId
而不是 Lombok 生成的 getPId
(我认为应该保留一个 JavaBeans) .
现在,有趣的是 Jackson 出于某种原因分别从 getCId
和 getPId
中制作了 cid
和 pid
...同时为 getcId
和 getpId
.
生成 cId
和 pId
因此,虽然 getcId
和 getpId
是 JavaBeans 的一个怪癖,但当 getter 被正确命名时,Jackson 似乎默认行为正确,即 getpId -> "pId"
和 getcId -> "cId"
。
鉴于 Lombok 生成 getPId
和 getCId
,这导致结果 JSON 中的全小写键,反序列化不起作用。
如果您不喜欢 getpId
/getcId
命名,那么您可能必须编写自己的 getter 并明确强制使用 属性 名称:
@Builder
@Jacksonized
class ComputationResult {
private final String pId;
private final String cId;
@JsonProperty("pId")
public String getPId() {
return pId;
}
@JsonProperty("cId")
public String getCId() {
return cId;
}
}
对于二传手,由于 final
字段,您已经不得不依赖 @Jacksonized
,所以这没有什么区别。请注意,必须省略 @Getter
,因为它会导致重复的属性(使用另一种命名方式)。
我使用 Jackson 很多年了,我不确定我是否遇到过这个问题。
在 Spring Boot 2.5.5 项目中使用 Jackson 2.12.5,我有一个需要序列化的对象。我对其他领域没有问题,但是这两个领域给我带来了问题:
@Jacksonized
@Builder
@Getter
public class ComputationResult {
private final String pId;
private final String cId;
... other fields ignored
}
如您所见,我也在使用 Lombok 注释。当“delombokized”时,吸气剂是:
public String getPId() {
return this.pId;
}
public String getCId() {
return this.cId;
}
序列化 POJO 时,我希望字段名称为“pId”和“cId”,但它们不是:我得到“pid”和“cid”,均为小写。我对其他领域没有问题,尊重案例。
这给我带来了一个问题,因为我需要序列化然后反序列化 POJO,反序列化失败是因为它无法将“cid”json 字段映射到“cId”java 字段。
有多种解决方法(我在现场使用 @JsonAlias("cid")
以允许反序列化),但我很困惑:这是杰克逊的预期行为吗?它会根据长度对字符串字段进行不同的处理吗?还是我不知道的 java beans 约定?
是否可以在 objectMapper 中设置 属性 来“修复”该行为,而无需实现我自己的 com.fasterxml.jackson.databind.PropertyNamingStrategy
?
问题似乎是由 属性 名称开头只有一个小写字符时 JavaBeans 方法如何生成引起的。你可能会对 getpId
and getcId
are indeed correctly named 和我一样感到惊讶。
简而言之,pId
正确地导致了 getter getpId
而不是 Lombok 生成的 getPId
(我认为应该保留一个 JavaBeans) .
现在,有趣的是 Jackson 出于某种原因分别从 getCId
和 getPId
中制作了 cid
和 pid
...同时为 getcId
和 getpId
.
cId
和 pId
因此,虽然 getcId
和 getpId
是 JavaBeans 的一个怪癖,但当 getter 被正确命名时,Jackson 似乎默认行为正确,即 getpId -> "pId"
和 getcId -> "cId"
。
鉴于 Lombok 生成 getPId
和 getCId
,这导致结果 JSON 中的全小写键,反序列化不起作用。
如果您不喜欢 getpId
/getcId
命名,那么您可能必须编写自己的 getter 并明确强制使用 属性 名称:
@Builder
@Jacksonized
class ComputationResult {
private final String pId;
private final String cId;
@JsonProperty("pId")
public String getPId() {
return pId;
}
@JsonProperty("cId")
public String getCId() {
return cId;
}
}
对于二传手,由于 final
字段,您已经不得不依赖 @Jacksonized
,所以这没有什么区别。请注意,必须省略 @Getter
,因为它会导致重复的属性(使用另一种命名方式)。