Jackson 反序列化默认值缺失

use*_*433 4 java jackson lombok deserialization json-deserialization

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

ObjectMapper mapper = new ObjectMapper();
ExampleDto ed = mapper.readValue(req.body(), ExampleDto.class);
Run Code Online (Sandbox Code Playgroud)

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

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

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

{name: "Foo"}
Run Code Online (Sandbox Code Playgroud)

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

编辑:不是重复的,因为我使用的是没有 Optionals 的 Lombok

Moh*_*avi 7

@AllArgsConstructor 创建以下构造函数

@ConstructorProperties({"name", "values"})
ExampleDto(String name, List<String> values) {
    this.name = name;
    this.values = values;
}
Run Code Online (Sandbox Code Playgroud)

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

当以下行执行时

mapper.readValue("{\"name\": \"Foo\"}", ExampleDto.class);
Run Code Online (Sandbox Code Playgroud)

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

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

  • @user2668735您可以将`@AllArgsConstructor`与`@AllArgsConstructor(onConstructor = @_(@JsonIgnore))`一起保留,并确保包含默认构造函数 (2认同)