【发布时间】:2019-06-18 10:01:36
【问题描述】:
我有一个第 3 方 Lombok 构建器 POJO,我无法修改它,我想使用 jackson 对其进行序列化。值得注意的是它没有有一个NoArgsConstructor。
@Data
@Builder
public class ExternalClass {
private String name;
private String data;
// etc.
}
从表面上看,这似乎很简单,但在实践中却令人难以置信地令人沮丧,因为每个可能的选项似乎都被不同的并发症所抵消。本质上,我很难让 external Lombok builder 与 jackson mixin 一起工作。
Lombok 生成 .name(String name) 风格的流畅设置器,而 Jackson 的内置构建器反序列化器需要 .withName(String name)。 Lombok 文档和其他地方的食谱(例如here)建议在预先声明的内部存根构建器上使用@JsonDeserialize(builder=ExternalClass.ExternalClassBuilder.class) 和@JsonPOJOBuilder(withPrefix="")。但这是不可能的,因为 Lombok 类位于外部库中。
将这些注释应用到 mixin 没有任何效果。
@JsonDeserialize(ExternalClass.ExternalClassBuilder.class)
public abstract class ExternalClassMixin {
@JsonPOJOBuilder(withPrefix="")
public static ExternalClassBuilder {
}
}
我发现唯一可行的方法是利用 @Builder 创建的包访问 AllArgsConstructor 并使用以下构造函数填充 mixin
public abstract class ExternalClassMixin {
@JsonCreator public ExternalClassMixin(
@JsonProperty("name") String name,
@JsonProperty("data") String data,
// etc.
) {}
}
这显然是不可取的,因为它需要显式地对每个类属性进行迭代和硬编码,这使得 mixin 对于外部 POJO 中的任何更改都很脆弱。
我的问题是 - 是否有一种健壮、可维护的方法来使用 Jackson 序列化这个外部构建器类而不用修改它,使用 mixin 或完整的反序列化器?
更新
我实现了@jan-rieke 的出色回答,包括使用反射来寻找内部构建器类的建议。
...
public Class<?> findPOJOBuilder(AnnotatedClass ac) {
Class<?> innerBuilder;
try {
innerBuilder = Class.forName(ac.getName()+"$"+ac.getRawType().getSimpleName()+"Builder");
log.info("Builder found: {}", ac.getName());
return innerBuilder;
} catch( ClassNotFoundException e ) {
return super.findPOJOBuilder(ac);
}
}
【问题讨论】:
-
你的问题解决了我的问题。我可以访问 JTwig 用来生成 API 客户端的外部 lombok 构建器。我可以将注释
@JsonDeserialize和@JsonPOJOBuilder添加到模板中。如果您对此做出回答,我将奖励您。
标签: java jackson mixins builder lombok