问题描述
我正在使用一个框架,该框架使用字段supplier
(它是抽象接口Supplier<T>
)执行类Config
的Java Jackson序列化.下面的接口是在框架中定义的,因此我无法更改/添加注释.
I'm working with a framework that performs Java Jackson serialization of class Config
with a field supplier
that is an abstract interface Supplier<T>
. The interfaces below are defined in the framework so I cannot change/add the annotations.
public interface Supplier<T> {
T get();
}
public interface Calculator {
}
@Data
@NoArgsConstructor
public class Config extends Serializable {
private Supplier<Calculator> supplier;
}
我有Supplier
的具体实现:
class MySupplier implements Supplier {
@Override Calculator get() { return ...; }
}
当我将Config
的实例序列化为JSON时,供应商字段将被序列化而没有类信息.据我了解,这是因为字段声明是抽象的.结果,在反序列化期间,杰克逊不知道如何实例化supplier
字段.
When I serialize an instance of Config
into JSON the supplier field is serialized without class information. From what I understand this is because the field declaration is abstract. As a result during deserialization Jackson doesn't know how to instantiate supplier
field.
"config" : {
...
"supplier" : { }
...
}
如何强制实现Supplier
接口,以将类名称信息添加到生成的JSON中以允许适当的反序列化?我无权执行执行序列化和反序列化的代码,只能操作Supplier
的实现.
How can I force my implementation of the Supplier
interface to add class name information into generated JSON to allow proper deserialization? I don't have access to the code that performs serialization and deserialization, I can only manipulate my implementation of Supplier
.
推荐答案
Jackson
允许使用称为MixIn
的功能来配置第三方类.有关更多信息,请阅读:
Jackson
allows to configure third party classes using feature called MixIn
. For more information read:
- Jackson Mixin to the Rescue
- Jackson Mix-In Annotations
您需要指定两个新接口,以允许您为其他类添加注释:
You need to specify two new interface which will allow you to add annotations for other classes:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME)
@JsonSubTypes({@JsonSubTypes.Type(value = MySupplier.class, name = "MySupplier")})
interface SupplierAnnotations {
}
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME)
@JsonSubTypes({
@JsonSubTypes.Type(value = MyCalculator.class, name = "MyCalculator"),
@JsonSubTypes.Type(value = HisCalculator.class, name = "HisCalculator") }
)
interface CalculatorAnnotations {
}
现在,您必须将新课程告知ObjectMapper
.您可以通过以下方式做到这一点:
Now, you have to inform ObjectMapper
about your new classes. You can do that in this way:
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(Calculator.class, CalculatorAnnotations.class);
mapper.addMixIn(Supplier.class, SupplierAnnotations.class);
您需要做的就是列出Suplier
和Calculator
接口的子类型.
Everything you need to do is to list sub types for Suplier
and Calculator
interfaces.
这篇关于杰克逊抽象接口的序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!