Java Jackson将空字段反序列化为POJO中的默认空列表

Java Jackson将空字段反序列化为POJO中的默认空列表,java,json,jackson,deserialization,lombok,Java,Json,Jackson,Deserialization,Lombok,我有一个带有lombok注释的POJO,我的JSON通过Jackson将其反序列化为: @Getter @ToString @NoArgsConstructor @Builder @AllArgsConstructor @EqualsAndHashCode @JsonIgnoreProperties(ignoreUnknown = true) public class ResponsePOJO { @JsonProperty("list-one") private List<

我有一个带有lombok注释的POJO,我的JSON通过Jackson将其反序列化为:

@Getter
@ToString
@NoArgsConstructor
@Builder
@AllArgsConstructor
@EqualsAndHashCode
@JsonIgnoreProperties(ignoreUnknown = true)
public class ResponsePOJO {
    @JsonProperty("list-one")
    private List<Object> list1 = Lists.newArrayList;
    @JsonProperty("list-two")
    private List<Object> list2 = Lists.newArrayList;
    @JsonProperty("list-three")
    private List<Object> list3 = Lists.newArrayList;
    @JsonProperty("list-four")
    private List<Object> list4 = Lists.newArrayList;
}
@Getter
@托斯特林
@诺尔格构装师
@建筑商
@AllArgsConstructor
@EqualsAndHashCode
@JsonIgnoreProperties(ignoreUnknown=true)
公共类响应{
@JsonProperty(“列表一”)
private List list1=Lists.newArrayList;
@JsonProperty(“列表二”)
private List list2=Lists.newArrayList;
@JsonProperty(“列表三”)
private List list3=Lists.newArrayList;
@JsonProperty(“列表四”)
private List list4=Lists.newArrayList;
}
当jackson试图反序列化只存在列表1和列表2的响应时,我希望生成的POJO将属性
list3
list4
作为默认值的空列表,但它们反序列化为
null

要确保所有属性都包含反序列化JSON中的对应值,或者包含默认赋值的空列表,缺少什么

---更新----
这不是一个问题,直到我从Spring 1.3.5升级到1.4.2,这也将我的Jackson版本从2.6.6升级到2.8.4

问题是您还添加了
@Builder
。初始化器被移动到构建器中,因为您不想运行代码两次

lombok的最新版本(1.16.16+)具有@Builder.Default,您可以使用它来影响该行为

您可以指示Jackson改用生成器,并使对象不可变。生成器适用于不可变的对象


披露:我是一名lombok开发者。

lombok的
@Builder
在这里不是直接的问题,因为Jackson不使用它进行反序列化。但是,Jackson正在使用带有参数的非默认构造函数(如果可用)进行对象实例化。否则,它将使用非参数构造函数。当您在
ResponsePOJO
上使用
@allargsconstuctor
时,Jackson将使用创建的构造函数,该构造函数如下所示:

public ResponsePOJO(List<Object> list1, List<Object> list2, List<Object> list3, List<Object> list4) {
    this.list1 = list1;
    this.list2 = list2;
    this.list3 = list3;
    this.list4 = list4;
}
在这里,Jackson仍将调用上面的所有参数构造函数,但如果某个字段不存在或不存在且为null(如果在某些情况下您可能期望null值,例如针对null值进行验证,则这可能会对您的业务逻辑产生下游影响),它将始终分配空列表


使用Jackson(com.fasterxml.Jackson)和Lombok的@Builder注释反序列化JSON对象时,我遇到了类似的问题。我可以通过在类内创建一个带@JsonPOJOBuilder注释的空构建器类,然后添加一个带有对空类的引用的@JsonDeserialize来解决这个问题。你可以找到更多信息

比如说,

@Getter
@ToString
@NoArgsConstructor
@Builder
@AllArgsConstructor
@EqualsAndHashCode
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonDeserialize(builder = ResponsePOJO.TypeBuilder.class)
public class ResponsePOJO {
    @JsonPOJOBuilder(withPrefix = "")
    @JsonIgnoreProperties(ModelUtils.TYPE_INFO_PROPERTY)

   public static class TypeBuilder{}//Empty builder class
                                    //Needed just to apply annotations
                                    //Lombok will fill it in later.

    @JsonProperty("list-one")
    private List<Object> list1 = Lists.newArrayList;
    @JsonProperty("list-two")
    private List<Object> list2 = Lists.newArrayList;
    @JsonProperty("list-three")
    private List<Object> list3 = Lists.newArrayList;
    @JsonProperty("list-four")
    private List<Object> list4 = Lists.newArrayList;
}
@Getter
@托斯特林
@诺尔格构装师
@建筑商
@AllArgsConstructor
@EqualsAndHashCode
@JsonIgnoreProperties(ignoreUnknown=true)
@JsonDeserialize(builder=ResponsePOJO.TypeBuilder.class)
公共类响应{
@JsonPOJOBuilder(前缀为“”)
@JsonIgnoreProperties(ModelUtils.TYPE\u INFO\u属性)
公共静态类TypeBuilder{}//空的生成器类
//只需要应用注释
//Lombok将在稍后填写。
@JsonProperty(“列表一”)
private List list1=Lists.newArrayList;
@JsonProperty(“列表二”)
private List list2=Lists.newArrayList;
@JsonProperty(“列表三”)
private List list3=Lists.newArrayList;
@JsonProperty(“列表四”)
private List list4=Lists.newArrayList;
}

Does Lists.newArrayList创建数组列表的新实例?正确
Lists.newArrayList()
是google guava库提供的一种方法,它听起来像什么就做什么。我还尝试通过lombok删除了
NoArgsConstructor
,并定义了我自己的,它将所有字段初始化为空列表,但仍然不起作用。你在类路径中有guava Jackson绑定模块吗?我还想知道,当你反序列化list1和list2节点时,你得到的列表类型是什么?如果是,请标记正确答案或添加答案我尝试添加
@Builder.Default
,定义了一个带有默认值的显式生成器,如中所述,甚至完全删除了
@Builder
,但问题仍然存在。
@Getter
@ToString
@NoArgsConstructor
@Builder
@AllArgsConstructor
@EqualsAndHashCode
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonDeserialize(builder = ResponsePOJO.TypeBuilder.class)
public class ResponsePOJO {
    @JsonPOJOBuilder(withPrefix = "")
    @JsonIgnoreProperties(ModelUtils.TYPE_INFO_PROPERTY)

   public static class TypeBuilder{}//Empty builder class
                                    //Needed just to apply annotations
                                    //Lombok will fill it in later.

    @JsonProperty("list-one")
    private List<Object> list1 = Lists.newArrayList;
    @JsonProperty("list-two")
    private List<Object> list2 = Lists.newArrayList;
    @JsonProperty("list-three")
    private List<Object> list3 = Lists.newArrayList;
    @JsonProperty("list-four")
    private List<Object> list4 = Lists.newArrayList;
}