这是我的课:
@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, andImpl
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 usingsetterPrefix
, this value is used. If you changed the name of thebuild()
method using usingbuildMethodName
, 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/