【问题标题】:Jackson deserialize default values missing杰克逊反序列化默认值丢失
【发布时间】:2018-07-21 09:50:10
【问题描述】:

我尝试使用以下代码反序列化我在 API 中收到的 JSON 对象:

ObjectMapper mapper = new ObjectMapper();
ExampleDto ed = mapper.readValue(req.body(), ExampleDto.class);

我的类使用 Lombok 生成构造函数、getter 和 setter,如下所示:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class ExampleDto {
    private String name = "";
    private List<String> values = new LinkedList<>();
}

这两个属性都应该是可选的,如果没有提供,则使用类定义中指定的默认值。但是,如果我现在尝试反序列化 JSON

{name: "Foo"}

values 字段是 null。根据我的理解,以及我找到的所有示例代码,values 应该是一个空列表。

编辑:不是重复的,因为我使用的是没有选项的龙目岛

【问题讨论】:

标签: java jackson deserialization json-deserialization lombok


【解决方案1】:

@AllArgsConstructor 创建如下构造函数

@ConstructorProperties({"name", "values"})
ExampleDto(String name, List<String> values) {
    this.name = name;
    this.values = values;
}

构造函数带有 @ConstructorProperties 注释,这意味着基于属性的创建者(带参数的构造函数或工厂方法)可用于从 JSON 对象实例化值,因此 jackson-databind 使用此构造函数从 ExampleDto 实例化对象类。

当下面一行执行时

mapper.readValue("{\"name\": \"Foo\"}", ExampleDto.class);

因为在提供的 JSON 中没有 values 的值,所以在调用构造函数时将 null 传递给第二个参数。

如果您删除 @AllArgsConstructor 注释,jackson-databind 将使用 setter 方法来初始化对象,在这种情况下,values 将不是 null

【讨论】:

  • 谢谢,这解决了我的问题。我一直讨厌这种问题。即使现在我知道了这个问题,也很难找到更多信息
  • 如果我们想保留@AllArgsConstructor ??我们如何告诉杰克逊不要使用这个 all args 构造函数?
  • @user2668735 你可以保留@AllArgsConstructor 和@AllArgsConstructor(onConstructor = @_(@JsonIgnore)),并确保包含一个默认构造函数
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-07
  • 1970-01-01
  • 2013-09-12
  • 2017-12-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多