问题
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