Make @JsonTypeInfo property optional

Posted by Mark Peters on Stack Overflow See other posts from Stack Overflow or by Mark Peters
Published on 2012-06-05T22:36:30Z Indexed on 2012/06/05 22:40 UTC
Read the original article Hit count: 2110

Filed under:
|
|

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.

© Stack Overflow or respective owner

Related posts about java

Related posts about JSON