问题
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;
}
I have a concrete implementation of Supplier
:
class MySupplier implements Supplier {
@Override Calculator get() { return ...; }
}
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" : { }
...
}
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
.
回答1:
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 {
}
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);
Everything you need to do is to list sub types for Suplier
and Calculator
interfaces.
来源:https://stackoverflow.com/questions/54224705/jackson-serialization-of-abstract-interface