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(Listanimals) { 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() + "]"; } }
put the json output as well!!!
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)
{
“@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
} ]
}