java - 使用混合的 Lombok @Builder 类的 Jackson 反序列化不起作用

标签 java jackson lombok jackson-databind

这是我的课:

@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]

最佳答案

这里的问题是 Jackson 需要一个无参数的构造函数或其他一些配置的方式来创建对象。

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

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

Lombok documentation对于 @Jacksonized 更详细地描述了这个注解:

The @Jacksonized annotation is an add-on annotation for @Builder and @SuperBuilder. It automatically configures the generated builder class to be used by Jackson's deserialization. It only has an effect if present at a context where there is also a @Builder or a @SuperBuilder; a warning is emitted otherwise.

[...]

In particular, the annotation does the following:

  • Configure Jackson to use the builder for deserialization using @JsonDeserialize(builder=_Foobar_._Foobar_Builder[Impl].class)) on the class (where Foobar is the name of the annotated class, and Impl is added for @SuperBuilder). (An error is emitted if such an annotation already exists.)
  • Copy Jackson-related configuration annotations (like @JsonIgnoreProperties) from the class to the builder class. This is necessary so that Jackson recognizes them when using the builder.
  • Insert @JsonPOJOBuilder(withPrefix="") on the generated builder class to override Jackson's default prefix "with". If you configured a different prefix in lombok using setterPrefix, this value is used. If you changed the name of the build() method using using buildMethodName, this is also made known to Jackson.
  • For @SuperBuilder, make the builder implementation class package-private.

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

关于java - 使用混合的 Lombok @Builder 类的 Jackson 反序列化不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63309223/

相关文章:

java - 为什么我的请求会同时命中两个 Controller ?

gradle - Delombok使用Gradle

java - Sonar "Singular Field"规则与 lombok-getter 矛盾

java - Gradle Swagger CodeGen DefaultGenerator CodegenConfigurator 添加 Lombok

spring-boot - Jackson - 通过 Jackson2ObjectMapperBuilderCustomizer 配置集合覆盖

java - Jackson 中的 JSON 属性文件不区分大小写

java - 为什么 Collection.equals() JavaDoc 说不可能同时正确实现 List 和 Set?

java - 使用数组列表将标记添加到 Google map 。安卓

Java 重写 hashCode() 得到 StackOverflowError

java - 使用 RestTemplate 反序列化嵌套对象