Can't deserialize extended abstract class json using Jackson in Java

Dhruv Batheja :

All the classes are defined as static. Objects are created in the main() function below:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.htrace.fasterxml.jackson.annotation.JsonSubTypes;
import org.apache.htrace.fasterxml.jackson.annotation.JsonTypeInfo;
import java.io.IOException;

public class Try {
public static class Zoo {
    public Animal getAnimal() {
        return animal;
    }

    public void setAnimal(Animal animal) {
        this.animal = animal;
    }

    Animal animal;

    @JsonCreator
    public Zoo(@JsonProperty("animal") Animal animal) {
        this.animal = animal;
    }

    public String toString() {
        return "|"+this.animal.toString()+"|";
    }
}

@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.WRAPPER_OBJECT,
        property = "type")
@JsonSubTypes({
        @JsonSubTypes.Type(value = Dog.class, name = "dog"),
        @JsonSubTypes.Type(value = Cat.class, name = "cat")
})
public static class Animal {
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String toString() {
        return this.name+"--"+this.type;
    }
    String name;
    String type;
    @JsonCreator
    public Animal(@JsonProperty("name") String name, @JsonProperty("type") String type) {
        this.name=name;
        this.type=type;
    }
}

public static class Dog extends Animal {
    public String getPower() {
        return power;
    }

    public void setPower(String power) {
        this.power = power;
    }

    String power;

    @JsonCreator
    public Dog(String name, @JsonProperty("power") String power) {
        super(name, "dog");
        this.power = power;
    }
}

public static class Cat extends Animal {
    public String getJump() {
        return jump;
    }

    public void setJump(String jump) {
        this.jump = jump;
    }

    String jump;

    @JsonCreator
    public Cat(String name, @JsonProperty("jump") String jump) {
        super(name, "cat");
        this.jump = jump;
    }
}

public static void main(String[] args) throws IOException {
    Try.Zoo zoo = new Try.Zoo(new Try.Dog("shaggy", "lick"));
    ObjectMapper mapper = new ObjectMapper();
    String jsonString=mapper.writeValueAsString(zoo);
    System.out.println(zoo.toString() + " " + jsonString);
    // works! Prints |shaggy--dog| {"animal":{"power":"lick","name":"shaggy","type":"dog"}}

    Try.Zoo zooDeserialized = mapper.readValue(jsonString, Try.Zoo.class);
    // Keeps throwing error: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "power" (class Try$Animal), not marked as ignorable (2 known properties: "type", "name"])

    System.out.println(zooDeserialized.toString());
}
}

I tried specifying JsonTypeInfo on the Animal class but still of no use. What am I doing wrong? Help.

Dawid D :

You are mixing imports from fasterxml and apache.htrace

try replacing

import org.apache.htrace.fasterxml.jackson.annotation.JsonSubTypes;
import org.apache.htrace.fasterxml.jackson.annotation.JsonTypeInfo;

with

import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

also correct :

  @JsonCreator
        public Dog(@JsonProperty("name") String name, @JsonProperty("power") String power) {
            super(name, "dog");
            this.power = power;
        }

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=419988&siteId=1