Suresh Payankannur

Saturday, September 14, 2013

Java/JSON Polymorphic Mapping Using Jackson

Jackson has a number of flexible ways to map Java objects to and from JSON. Some of them are as follows:

  1. @JsonProperty to change the name of the property output to JSON
  2. @JsonSerialize/@JsonDeserialize to change the type of the object or to provide custom serializer
  3. @JsonIgnore to ignore properties
  4. Mixins to control runtime annotations during serialization & deserialization

Here in this post, I focus on serialization and deserialization of polymorphic types using @JsonPropertyInfo to inject an extra property called type to distinguish between different object types.

Model

import com.fasterxml.jackson.annotation.*;

@JsonTypeInfo(use=JsonTypeInfo.Id.NAME,
              include=JsonTypeInfo.As.PROPERTY,
              property="type")
@JsonSubTypes({
        @JsonSubTypes.Type(value=Dog.class, name="dog"),
        @JsonSubTypes.Type(value=Cat.class, name="cat"),
    })
public abstract class Animal {
    public Animal() {
    }
    public Animal(String name) {
        this.name = name;
    }
    public String getName() {
        return this.name;
    }
    public void setName(String s) {
        this.name = s;
    }
    public Animal getParent() {
        return this.parent;
    }
    public void setParent(Animal p) {
        this.parent = p;
    }
    private String name;
    private Animal parent;
}


@JsonTypeName("dog")
public class Dog extends Animal {
    public Dog() {
    }
    public Dog(String name) {
        super(name);
    }
}

@JsonTypeName("cat")
public class Cat extends Animal {
    public Cat() {
    }
    public Cat(String name) {
        super(name);
    }
}

Driver


Now create a Zoo class holding the animals. And the driver to test the model
import java.util.ArrayList;
import java.util.List;

import com.fasterxml.jackson.databind.ObjectMapper;

public class Zoo {
    public static void main(String... args) throws Exception {
        Zoo zoo = createZoo();

        ObjectMapper mapper = new ObjectMapper();
        String json1 = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(zoo);
        System.out.println("+++>>>" + json1);

        zoo = mapper.readValue(json1, Zoo.class);

        String json2 = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(zoo);

        System.out.println("Equals: " + json1.equals(json2));
    }

    private static Zoo createZoo() {
        Zoo zoo = new Zoo();

        Dog dog1 = new Dog("Dog1");
        Dog dog2 = new Dog("Dog2");
        Cat cat1 = new Cat("Cat1");
        Cat cat2 = new Cat("Cat2");

        dog2.setParent(dog1);
        cat2.setParent(cat1);

        zoo.add(dog1);
        zoo.add(dog2);
        zoo.add(cat1);
        zoo.add(cat2);

        return zoo;
    }
    public void add(Animal animal) {
        animals.add(animal);
    }

    public void setAnimals(List<Animal> list) {
        this.animals = list;
    }
    public List<Animal> getAnimals() {
        return this.animals;
    }
    private List<Animal> animals = new ArrayList<Animal>();
}

Result

{
 "animals" : [ {
    "type" : "dog",
    "name" : "Dog1",
    "parent" : null
  }, {
    "type" : "dog",
    "name" : "Dog2",
    "parent" : {
      "type" : "dog",
      "name" : "Dog1",
      "parent" : null
    }
  }, {
    "type" : "cat",
    "name" : "Cat1",
    "parent" : null
  }, {
    "type" : "cat",
    "name" : "Cat2",
    "parent" : {
      "type" : "cat",
      "name" : "Cat1",
      "parent" : null
    }
  } ]
}

Equals: true

1 comment:

  1. Hi, Great.. Tutorial is just awesome..It is really helpful for a newbie like me.. I am a regular follower of your blog. Really very informative post you shared here. Kindly keep blogging. If anyone wants to become a Java developer learn from Java Training in Chennai. or learn thru Java Online Training from India . Nowadays Java has tons of job opportunities on various vertical industry.

    ReplyDelete

Blog Archive

Scroll To Top