杰克逊反序列化失败,因为lombok创建了非默认构造函数 [英] Jackson Deserialization Fails because of non-default constructor created by lombok

查看:1105
本文介绍了杰克逊反序列化失败,因为lombok创建了非默认构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Jackson可以在2.6.5中反序列化以下类的json,但在2.8.8中失败.

Jackson can deserialize json for the following class in 2.6.5 but fails in 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()构造函数.是什么导致此问题?

I have found that the Child constructor created by lombok is causing this error. When I get rid of the lombok annotation or if I create the constructor manually, this stops happening. Either way, it should be using the no-args Child() constructor. What is causing this issue?

推荐答案

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

Lombok adds the annotation @ConstructorProperties({"parent"}) to the generated constructor. In Jackson 2.8.8, this causes the constructor to be treated as a "delegate creator".

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

A delegate creator allows Jackson to deserialize json for one type of object into another type of Java object.

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

In this case, because lombok generates the constructor @ConstructorProperties({"parent"}) Child(Parent parent) {...} Jackson will try to deserialize the child json as a Parent object, which could then be passed into the constructor to create a Child. It then throws the exception because childId is not a field in Parent.

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

One workaround is to configure the ObjectMapper used to deserialize the JSON with a custom JacksonAnnotationIntrospector so it won't interpret the constructor as a delegate creator.

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

更新

项目lombok的版本1.16.20确实确实默认将lombok.anyConstructor.suppressConstructorProperties设置为true,正如Roel指出的那样. 因此,将lombok升级到最新版本是解决此问题的另一种方法.

Version 1.16.20 of project lombok did indeed default lombok.anyConstructor.suppressConstructorProperties to true as Roel indicated might happen in his comment. That makes upgrading lombok to the latest version another fix for this issue.

这篇关于杰克逊反序列化失败,因为lombok创建了非默认构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆