使用mixin的Lombok @Builder类的Jackson类化不起作用

mec1mxoz  于 7个月前  发布在  其他
关注(0)|答案(2)|浏览(53)

这是我的班级:

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

Lombok @Builder将添加all args构造函数。
我需要把一个字符串转换成一个POJO对象。
我创建了以下包含所有三个属性的Jacksonmixin:

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

hec6srdp1#

我找到了答案。
添加lombok.config文件,其内容为:

lombok.anyConstructor.addConstructorProperties=true
50few1ms

50few1ms2#

这里的问题是,Jackson期望一个无参数的构造函数或其他一些创建对象的配置方式。但是,由于A上的@Builder注解,不存在无参数构造函数,只有Lombok生成的全参数构造函数A(int id, String name, String lastName)
从Lombok v1.18.14开始,可以将@Jacksonized注解添加到带有@Builder注解的类中,这会自动将构建器配置为用于Jackson化。

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

Lombok documentation for @Jacksonized更详细地描述了此注解:
@Jacksonized注解是@Builder@SuperBuilder的附加注解。它自动配置生成的构建器类,以供Jackson的示例化使用。它只有在存在@Builder@SuperBuilder的上下文中才有效;否则发出警告。
[...]
特别地,注解执行以下操作:

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

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

相关问题