当前位置: 首页 > 知识库问答 >
问题:

Jackson使用混音对Lombok@Builder类进行反序列化不起作用

鲁淇
2023-03-14

这是我的班级:

@Builder
@Value
public class A {
    int id;
    String name;
    @NonNull String lastName;
}

Lombok@Builder将添加所有参数构造函数。

我需要将一个字符串反序列化为一个POJO对象。

我创建了以下包含所有三个属性的Jackson mixin:

public abstract class AMixin {
    public AMixin(@JsonProperty("name") String name,
                  @JsonProperty("id") int id,
                  @JsonProperty("lastName") String lastName) {
    }

    @JsonProperty("name")
    abstract String getName();

    @JsonProperty("id")
    abstract int getId();

    @JsonProperty("lastName")
    abstract String getLastName();

}

我这样描述:

public static void main(String[] args) throws Exception {


        ObjectMapper mapper = new ObjectMapper();
        mapper.addMixIn(A.class, AMixin.class);

        String ss = "{\"id\":1,\"name\":\"some name\",\"lastName\":\"some name\"}\n";
        A c = mapper.readValue(ss, A.class);
    }

但是我得到了这个错误:

Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.bla.test.A` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (String)"{"id":1,"name":"some name","lastName":"some name"}
"; line: 1, column: 2]

共有2个答案

丁业
2023-03-14

我找到了答案。

添加包含以下内容的龙目岛配置文件:

lombok.anyConstructor.addConstructorProperties=true
晁璞
2023-03-14

这里的问题是Jackson希望使用无参数构造函数或其他配置的方式来创建对象。

从Lombok v1.18.14开始,可以将@Jacksonize注释添加到带有@Builder注释的类中,以自动配置用于Jackson反序列化的构建器。

@Jacksonized
@Builder
@Value
public class A {
    int id;
    String name;
    @NonNull String lastName;
}

@Jacksonize的Lombok留档更详细地描述了此注释:

@Jacksonized注释是@Builder@SuperBuilder的附加注释。它自动配置生成的生成器类,以供Jackson的反序列化使用。只有在同时存在@Builder@SuperBuilder的上下文中,它才具有效果;否则发出警告。

[...]

特别是,注释执行以下操作:

  • 配置Jackson使用构建器对类进行反序列化,在类上使用@JsonDeserializ(builder=_Foobar_._Foobar_Builder[Impl]. class))(其中Fubar是带注释类的名称,Impl是为@SuperBuilder添加的)。(如果这样的注释已经存在,则会发出错误。)
  • 将Jackson相关的配置注释(如@JsonIgnoreProperties)从类复制到构建器类。这是必要的,以便Jackson在使用构建器时识别它们。
  • 在生成的构建器类上插入@JsonPOJOBuilder(with Prefix=")以覆盖Jackson的默认前缀“with”。如果您使用setterPrefix在lombok中配置了不同的前缀,则使用此值。如果您使用buildomeodName更改了build()方法的名称,这也会让Jackson知道。
  • 对于@SuperBuilder,使构建器实现类包私有。

注意:此问题与混音的使用无关,可以通过将Jackson配置从混音移至类本身并观察问题仍然存在来验证。

 类似资料:
  • 将这些注释应用于mixin没有任何效果。 我发现唯一有效的方法是利用创建的包访问AllArgsConstructor,并用以下构造函数填充mixin 这显然是不可取的,因为它需要显式地迭代和硬编码每个类属性,使得mixin对外部POJO中的任何更改都很脆弱。

  • 问题内容: 我整天都在寻找可以解决这个问题的东西,但是到目前为止我还没有碰到很多运气。 我的问题很简单:如何使用Jackson正确反序列化匿名对象。 在出现异常之前,此输出为:JSON = [“ com.foo.test.JacksonTest $ 1”,{“ value”:5}]: 线程“主”中的异常com.fasterxml.jackson.databind.JsonMappingExcept

  • 问题内容: 我使用杰克逊测试了Scala案例类的序列化。 DeserializeTest.java 福斯卡拉 当我运行上述Java类时,抛出了一个异常: 我如何(反)序列化Scala案例类? 问题答案: Jackson希望您的类是JavaBean,这意味着它希望该类的每个属性都具有getX()和/或setX()。 选项1 您可以使用注释BeanProperty在Scala中创建JavaBean类。

  • 来自REST服务的json对象 使用JacksonInFiveMinutes中的代码 ObjectMapper mapper=new ObjectMapper(); Map userData=mapper.read值(webResource.queryParams(queryParams). get(String.class);, Map.class); 在哪里: 从REST服务返回json 从J

  • 试图将JSON反序列化为我创建的Java bean。对杰克逊和这项努力来说真的很新鲜,所以请容忍我。我有以下几点: 由于JSON中的对象被反复使用,我的Java Bean被分解为几个部分,因此: ...和以类似方式实现的另一个BlockBean类(为简洁起见省略)。我使用杰克逊来完成这个任务,我的问题是——杰克逊中是否有序列化和反序列化的机制?理想情况下,我想要这样的东西(下面是伪代码,因为我无法