1

I need deserialize JSON to object depends on the type. I have the following JSON:

{
   "type": "dog",
   "name": "dogName"
}

and I have the following classes:

@JsonIgnoreProperties(ignoreUnknown = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes({
        @JsonSubTypes.Type(value = Dog.class, name = "dog"),
        @JsonSubTypes.Type(value = Cat.class, name = "cat"),
})
public abstract class Animal {
    @JsonProperty("type")
    public String type;
    public String name;
}

public class Dog extends Animal {
   ...
}

public class Cat extends Animal {
   ...
}

and when I try to deserialize all is going fine:

public class StartPdfApp {
    public static void main(String[] args) throws IOException {
        ...
        ObjectMapper mapper = new ObjectMapper();
        Animal animal = mapper.readValue(json, Animal.class);
        System.out.println("TYPE: " + animal.type);        // always null
        System.out.println("DOG: " + (animal instanceof Dog));
        System.out.println("CAT: " + (animal instanceof Cat));
    }
}

but when I want to get field value type I have null How can I fix it?

John
  • 1,375
  • 4
  • 17
  • 40
  • did you trying to use json api? https://jsonapi.org/ – Abbas Torabi Nov 18 '19 at 13:04
  • Probably, you have to use `JsonTypeInfo.As.EXISTING_PROPERTY`. Also see other `Dog` and `Cat` examples: [Java unmarshilling JSON data containg abstract type](https://stackoverflow.com/questions/16800896/java-unmarshilling-json-data-containg-abstract-type), [Jackson polymorphic deserialisation without using annotations](https://stackoverflow.com/questions/57078055/jackson-polymorphic-deserialisation-without-using-annotations) – Michał Ziober Nov 18 '19 at 13:18

1 Answers1

5

You need to tell Jackson to pass the type field to the deserializer, otherwise it is used only for type discrimination. This is done with the property visible in the @JsonTypeInfo annotation. Also, not sure if strictly necessary in your case, but I specify the type info to use an existing property:

@JsonIgnoreProperties(ignoreUnknown = true)
@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.EXISTING_PROPERTY,
    property = "type",
    visible = true)
@JsonSubTypes({
        @JsonSubTypes.Type(value = Dog.class, name = "dog"),
        @JsonSubTypes.Type(value = Cat.class, name = "cat"),
})
public abstract class Animal {
    @JsonProperty("type")
    public String type;
    public String name;
}
Pedro
  • 1,032
  • 6
  • 12