首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java Jackson将空字段反序列化为POJO中的默认空列表

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

Stack Overflow用户
提问于 2017-12-18 06:01:03
回答 3查看 5.7K关注 0票数 2

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

代码语言:javascript
复制
@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;
}

当jackson试图反序列化一个只有list-one & list-two的响应时,我希望得到的POJO将属性list3list4作为一个空列表,这是默认值,但是它们被反序列化为null

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

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

EN

回答 3

Stack Overflow用户

发布于 2018-01-20 17:30:42

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

代码语言:javascript
复制
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;
}

当调用此构造函数时,您的默认值将被丢弃,并为JSON中不存在的字段分配null

虽然@Builder需要所有参数构造函数,但您有几种方法可以解决此问题:

  1. 不使用@Builder和remove @AllArgsConstructor -有时你可能不需要它们中的任何一个,但这取决于你的用例
  2. Remove @AllArgsConstructor并创建自定义构造器,它不是使用内部的所有参数构造函数,而是一个无参数构造函数。
  3. 使用<@Builder>d15@AllArgsConstructor>并创建自定义所有参数构造函数,如下所示:

公共ResponsePOJO(List list1,List list2,List list3,List list4) { this.list1 = list1 == null?Lists.newArrayList():list1;this.list2 = list2 == null?Lists.newArrayList():list2;this.list3 = list3 == null?Lists.newArrayList():list3;this.list4 = list4 == null?Lists.newArrayList():list4;}

在这里,Jackson仍然会调用上面的所有参数构造函数,但是如果某些字段不存在或者存在并且是null (如果在某些情况下您可能期望NULL值,例如针对空性的验证),这可能会对您的业务逻辑产生下游影响,那么它将始终分配空列表。

票数 3
EN

Stack Overflow用户

发布于 2017-12-18 17:34:35

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

lombok的最新版本(1.16.16+)提供了可以用来影响该行为的@Builder.Default。

您可以指示Jackson使用构建器,并使您的对象不可变。构建器是为不可变对象设计的。

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

票数 1
EN

Stack Overflow用户

发布于 2018-02-21 05:16:12

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

例如,

代码语言:javascript
复制
@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;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47859884

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档