Reputation: 6729
I have several Json strings as follows:
{"type1": {"name": "Arnold"}}
{"type2": {"id": "abcd", "job": "plumber"}}
The thing I want to end up with is converting a json string to one of the classes Type1
or Type2
depending on the root property of element:
// Type0 abstract class
public abstract class Type0 {
}
// Type1 class.. convert to it if {"type1": {...}}
@JsonRootName(value = "type1")
public class Type1 extends Type0 {
@JsonProperty("name")
String name;
}
// Type2 class.. convert to it if {"type2": {...}}
@JsonRootName(value = "type2")
public class Type2 extends Type0 {
@JsonProperty("id")
String id;
@JsonProperty("job")
String job;
}
How to configure the ObjectMapper
of Jackson so that I can achieve that deserialization? I think of a logic like the follows, is it doable:
ObjectMapper mapper = new ObjectMapper();
result = mapper.readValue(jsonString, Type0.class);
//TODO: code for deciding whether result is Type1 or Type2 and casting to it
Upvotes: 2
Views: 688
Reputation: 22224
Jackson supports such a case with WRAPPER_OBJECT. Annotate the abstract class like this:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT)
@JsonSubTypes({
@JsonSubTypes.Type(name = "type1", value = Type1.class),
@JsonSubTypes.Type(name = "type2", value = Type2.class)})
abstract class Type0 {}
and then when parsing Type0.class
with readValue
you will get an instance of the appropriate derived class. You don't need @JsonRootName
over the derived classes.
Upvotes: 2