Java Jackson – Json Polymorphism

Also see json simple org.json

Jackson provides a way to maintain sub type information while serializing java objects. It is possible to recreate the exact sub type. The type information can be embedded into the json as a property. In the example below we create a zoo, that has a list of animals. The animal may be an elephant or a lion, and they both extend the Animal abstract class. While deserializing we want to create the exact animal type. We also demonstrate the use of @JsonTypeInfo and @JsonSubTypes annotations.

Data Serialization and Polymorphism Example

package com.studytrails.json.jackson;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class SerializeExample1 {
	private static String outputFile = "zoo.json";

	public static void main(String[] args) throws JsonGenerationException, JsonMappingException, IOException {
		// let start creating the zoo
		Zoo zoo = new Zoo("Samba Wild Park", "Paz");
		Lion lion = new Lion("Simba");
		Elephant elephant = new Elephant("Manny");
		List<Animal> animals = new ArrayList<>();
		animals.add(lion);
		animals.add(elephant);
		zoo.setAnimals(animals);

		ObjectMapper mapper = new ObjectMapper();
		mapper.writerWithDefaultPrettyPrinter().writeValue(new FileWriter(new File(outputFile)), zoo);
	}
}

Before we look at the various classes, lets also see how to deserialize this

package com.studytrails.json.jackson;

import java.io.File;
import java.io.IOException;

import org.apache.commons.io.FileUtils;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class DeSerializeExample1 {

	public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
		ObjectMapper mapper = new ObjectMapper();
		Zoo zoo = mapper.readValue(FileUtils.readFileToByteArray(new File("zoo.json")), Zoo.class);
		System.out.println(zoo);
	}
}

Zoo class

package com.studytrails.json.jackson;

import java.util.List;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;

@JsonTypeInfo(use = JsonTypeInfo.Id.MINIMAL_CLASS, include = As.PROPERTY, property = "@class")
public class Zoo {

	public String name;
	public String city;
	public List<Animal> animals;

	@JsonCreator
	public Zoo(@JsonProperty("name") String name, @JsonProperty("city") String city) {
		this.name = name;
		this.city = city;
	}

	public void setAnimals(List animals) {
		this.animals = animals;
	}

	@Override
	public String toString() {
		return "Zoo [name=" + name + ", city=" + city + ", animals=" + animals + "]";
	}

}




Animal Abstract class

package com.studytrails.json.jackson;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = As.PROPERTY, property = "@class")
@JsonSubTypes({ @Type(value = Lion.class, name = "lion"), @Type(value = Elephant.class, name = "elephant") })
public abstract class Animal {
	@JsonProperty("name")
	String name;
	@JsonProperty("sound")
	String sound;
	@JsonProperty("type")
	String type;
	@JsonProperty("endangered")
	boolean endangered;

}

Lion class

package com.studytrails.json.jackson;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

public class Lion extends Animal {

	private String name;

	@JsonCreator
	public Lion(@JsonProperty("name") String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public String getSound() {
		return "Roar";
	}

	public String getType() {
		return "carnivorous";
	}

	public boolean isEndangered() {
		return true;
	}

	@Override
	public String toString() {
		return "Lion [name=" + name + ", getName()=" + getName() + ", getSound()=" + getSound() + ", getType()=" + getType() + ", isEndangered()="
				+ isEndangered() + "]";
	}

}

Elephant class

package com.studytrails.json.jackson;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

public class Elephant extends Animal {

	@JsonProperty
	private String name;

	@JsonCreator
	public Elephant(@JsonProperty("name") String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public String getSound() {
		return "trumpet";
	}

	public String getType() {
		return "herbivorous";
	}

	public boolean isEndangered() {
		return false;
	}

	@Override
	public String toString() {
		return "Elephant [name=" + name + ", getName()=" + getName() + ", getSound()=" + getSound() + ", getType()=" + getType()
				+ ", isEndangered()=" + isEndangered() + "]";
	}

}

3 thoughts on “Java Jackson – Json Polymorphism”

  1. Hi

    In the class DeSerializeExample1 if you trying get name of animal it gets an error :

    –> System.out.println(zoo.animals.get(0).name); ==> result : “null”

    –> System.out.println(zoo.animals.get(0).name.toString());
    Exception in thread “main” java.lang.NullPointerException
    at polymorphismZoo.DeSerializeExample1.main(DeSerializeExample1.java:19)

    Reply
  2. {
    “@class” : “Zoo”,
    “name” : “Samba Wild Park”,
    “city” : “Paz”,
    “animals” : [ {
    “@class” : “Lion”,
    “name” : “Simba”,
    “sound” : “Roar”,
    “type” : “carnivorous”,
    “endangered” : true
    }, {
    “@class” : “Elephant”,
    “name” : “Manny”,
    “sound” : “trumpet”,
    “type” : “herbivorous”,
    “endangered” : false
    } ]
    }

    Reply

Leave a Comment