Jackson 使用 mixin 对 Lombok @Builder 类进行反序列化不起作用
Posted
技术标签:
【中文标题】Jackson 使用 mixin 对 Lombok @Builder 类进行反序列化不起作用【英文标题】:Jackson deserialization of a Lombok @Builder class using a mixin is not working 【发布时间】:2020-11-28 05:30:45 【问题描述】:这是我的课:
@Builder
@Value
public class A
int id;
String name;
@NonNull String lastName;
Lombok @Builder
将添加 all args 构造函数。
我需要将一个字符串反序列化为一个 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]
【问题讨论】:
您是否尝试添加 @NoArgsConstructor ?如果它不起作用,请检查这个***.com/questions/51464720/… @TraychoIvanov 我不想要没有参数的构造函数。我的类是最终的,它的所有字段都是最终的,必须在启动阶段(构造函数)声明 在这种情况下,您需要使用@JsonDeserialize
的这种方法,这里有一个很好的例子 ***.com/a/48801237/9671280
@TraychoIvanov 混合的整个想法是避免在你的 POJO 中添加 Jackson 注释,所以我想知道为什么我的混合不起作用。
这能回答你的问题吗? Lombok 1.18.0 and Jackson 2.9.6 not working together
【参考方案1】:
我找到了答案。
添加带有内容的 lombok.config 文件:
lombok.anyConstructor.addConstructorProperties=true
【讨论】:
【参考方案2】:这里的问题是,Jackson 需要一个无参数的构造函数或其他配置的创建对象的方式。
从 Lombok v1.18.14 开始,@Jacksonized
注释可以添加到带有 @Builder
注释的类中,以自动配置生成器以用于 Jackson 反序列化。
@Jacksonized
@Builder
@Value
public class A
int id;
String name;
@NonNull String lastName;
@Jacksonized
的 Lombok documentation 更详细地描述了这个注解:
@Jacksonized
注释是@Builder
和@SuperBuilder
的附加注释。它会自动配置生成的构建器类以供Jackson 的反序列化使用。它仅在存在@Builder
或@SuperBuilder
的上下文中才有效;否则会发出警告。[...]
具体来说,注解做了以下事情:
将 Jackson 配置为使用构建器进行反序列化,在类上使用@JsonDeserialize(builder=_Foobar_._Foobar_Builder[Impl].class))
(其中 Foobar 是带注释的类的名称,Impl
是为@SuperBuilder
添加的)。 (如果这样的注释已经存在,则会发出错误。) 将 Jackson 相关的配置注释(如@JsonIgnoreProperties
)从类复制到构建器类。这是必要的,以便杰克逊在使用构建器时识别它们。 在生成的构建器类中插入@JsonPOJOBuilder(withPrefix="")
以覆盖Jackson 的默认前缀“with”。如果您在 lombok 中使用setterPrefix
配置了不同的前缀,则使用此值。如果您使用buildMethodName
更改了build()
方法的名称,Jackson 也会知道这一点。 对于@SuperBuilder
,将构建器实现类设为包私有。
注意:此问题与 mixin 的使用无关,可以通过将 Jackson 配置从 mixin 移动到类本身并观察问题仍然存在来验证。
【讨论】:
以上是关于Jackson 使用 mixin 对 Lombok @Builder 类进行反序列化不起作用的主要内容,如果未能解决你的问题,请参考以下文章
Lombok、Spring mongodb 和 jackson 构造函数问题
使用 lombok @Builder 时通过 Jackson 反序列化“2021-09-24 00:00:00”日期格式