Let's start with some terminology. When dealing with Jackson,
serializing is the act of converting your Java object to JSON and
deserializing is the opposite, i.e. converting JSON to your Java object.
Polymorphic types present a challenge when deserializing. How does the mapper know which Java subtype object to create? The soultion is to include some extra metadata to the JSON which specifies the subtype.
Jackson supports a number of ways of doing this - see
JacksonPolymorphicDerialization. I found this page a little tricky to understand, particularly the subject of using a logical name to determine type.
I specifically did not want to use JsonTypeInfo.Id.CLASS or even JsonTypeInfo.Id.MINIMAL_CLASS. These seem like bad practice as you end up exposing implementation details in the JSON. Do you really want to be exposing the fully qualified name to your application class? Also, in terms of efficiency, it's an awful lot of wasted characters.
So I went for the JsonTypeInfo.Id.NAME solution, here's a dumbed-down example:
@JsonTypeInfo(use=Id.NAME, include=As.PROPERTY, property="type")
@JsonSubTypes({
@JsonSubTypes.Type(value=SubOne.class, name="One"),
@JsonSubTypes.Type(value=SubTwo.class, name="Two")
})
public class Base {
}
public class SubOne extends Base {
private String att1;
}
public class SubTwo extends Base {
private String att2;
}
The property="type" refers to a field in the JSON only, it is not deserialized into the Java object. Here is some example JSON that you could now feed into your deserializer:
{"type": "One"
, "att1": "hello from SubOne!"}
or
{"type": "Two"
, "att2": "hello from SubTwo!"
}
Note there are several different ways to solve this problem, so it's worth investing some time to digest the Jackson documentation.