由于lombok

时间:2017-12-01 16:59:55

标签: java spring lombok jackson2 jackson-databind

杰克逊可以在2.6.5中对json进行以下类的反序列化,但在2.8.8中失败。

型号:

public static class Parent {
    public long id;
    public List<Child> children;
}

@RequiredArgsConstructor
public static class Child {
    public long childId;

    @NonNull
    @JsonIgnore
    public Parent parent;

    public Child() { }
}

JSON:

{
  "id": 1,
  "children": [
    {
      "childId": 2
    }
  ]
}

例外是:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "childId" (class Parent), not marked as ignorable (2 known properties: "children", "id"])

我发现lombok创建的Child构造函数导致了这个错误。当我摆脱lombok注释或者如果我手动创建构造函数时,这将停止发生。无论哪种方式,它应该使用no-args Child()构造函数。是什么导致了这个问题?

1 个答案:

答案 0 :(得分:3)

Lombok将注释@ConstructorProperties({"parent"})添加到生成的构造函数中。在Jackson 2.8.8中,这会导致构造函数被视为“委托创建者”。

委托创建者允许Jackson将一种类型的对象的json反序列化为另一种类型的Java对象。

在这种情况下,因为lombok生成构造函数@ConstructorProperties({"parent"}) Child(Parent parent) {...},Jackson将尝试将子json反序列化为Parent对象,然后可以将其传递给构造函数以创建Child。然后抛出异常,因为childId不是Parent中的字段。

一种解决方法是配置用于使用自定义ObjectMapper反序列化JSON的JacksonAnnotationIntrospector,以便它不会将构造函数解释为委托创建者。

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector().setConstructorPropertiesImpliesCreator(false));

<强>更新

项目lombok的1.16.20版确实默认lombok.anyConstructor.suppressConstructorProperties为true,因为Roel表示可能会在他的评论中出现。 这使得lombok升级到最新版本的另一个修复此问题。