我有一个带有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;
}当jackson试图反序列化一个只有list-one & list-two的响应时,我希望得到的POJO将属性list3和list4作为一个空列表,这是默认值,但是它们被反序列化为null。
要确保所有属性要么包含反序列化的JSON中的相应值,要么包含默认赋值的空列表,那么缺少什么?
-更新-在我从Spring 1.3.5升级到1.4.2之前,这不是一个问题,这也将我的Jackson版本从2.6.6升级到了2.8.4
发布于 2018-01-20 17:30:42
Lombok的@Builder在这里不是一个直接的问题,因为Jackson没有使用它来进行反序列化。但是,Jackson正在使用带参数的非默认构造函数(如果可用)来实例化对象。否则,它将使用非参数构造函数。当你在ResponsePOJO上使用@AllArgsConstructor时,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;
}当调用此构造函数时,您的默认值将被丢弃,并为JSON中不存在的字段分配null。
虽然@Builder需要所有参数构造函数,但您有几种方法可以解决此问题:
@Builder和remove @AllArgsConstructor -有时你可能不需要它们中的任何一个,但这取决于你的用例@AllArgsConstructor并创建自定义构造器,它不是使用内部的所有参数构造函数,而是一个无参数构造函数。@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值,例如针对空性的验证),这可能会对您的业务逻辑产生下游影响,那么它将始终分配空列表。
发布于 2017-12-18 17:34:35
问题是您还添加了@Builder。初始化器被移到构建器中,因为您不想运行代码两次。
lombok的最新版本(1.16.16+)提供了可以用来影响该行为的@Builder.Default。
您可以指示Jackson使用构建器,并使您的对象不可变。构建器是为不可变对象设计的。
披露:我是一名lombok开发者。
发布于 2018-02-21 05:16:12
我在使用JSON (com.fasterxml.jackson)和Lombok的@Builder注解反序列化JSON对象时遇到了类似的问题。通过在类中创建一个带有@JsonPOJOBuilder注释的空Builder类,然后添加一个引用到该空类的@JsonDeserialize,我能够解决这个问题。你可以找到更多信息here
例如,
@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;
}https://stackoverflow.com/questions/47859884
复制相似问题