I'm using @JsonTypeInfo
to instruct Jackson to look in the @class
property for concrete type information. However, sometimes I don't want to have to specify @class
, particularly when the subtype can be inferred given the context. What's the best way to do that?
Here's an example of the JSON:
{ "owner": {"name":"Dave"}, "residents":[ {"@class":"jacksonquestion.Dog","breed":"Greyhound"}, {"@class":"jacksonquestion.Human","name":"Cheryl"}, {"@class":"jacksonquestion.Human","name":"Timothy"} ] }
and I'm trying to deserialize them into these classes (all in jacksonquestion.*
):
public class Household { private Human owner; private List<Animal> residents; public Human getOwner() { return owner; } public void setOwner(Human owner) { this.owner = owner; } public List<Animal> getResidents() { return residents; } public void setResidents(List<Animal> residents) { this.residents = residents; } } public class Animal {} public class Dog extends Animal { private String breed; public String getBreed() { return breed; } public void setBreed(String breed) { this.breed = breed; } } public class Human extends Animal { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
using this config:
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class") private static class AnimalMixin { } //... ObjectMapper objectMapper = new ObjectMapper(); objectMapper.getDeserializationConfig().addMixInAnnotations(Animal.class, AnimalMixin.class); Household household = objectMapper.readValue(json, Household.class); System.out.println(household);
As you can see, the owner is declared as a Human, not an Animal, so I want to be able to omit @class
and have Jackson infer the type as it normally would.
When I run this though, I get
org.codehaus.jackson.map.JsonMappingException: Unexpected token (END_OBJECT), expected FIELD_NAME: missing property '@class' that is to contain type id (for class jacksonquestion.Human)
Since "owner" doesn't specify @class
.
Any ideas? One initial thought I had was to use @JsonTypeInfo
on the property rather than the type. However, this cannot be leveraged to annotate the element type of a list. (Incorrect, see answer)