JAVA - JSON Serializing and De-serializing of polymorphic objects

I was recently faced with a slightly different problem, of how to serialize and deserialize polymorphic objects using JSON, and as I've now successfully fixed the problem I wanted to share with you how I did it.

What are Polymorphic objects?

Polymorphic objects, in the software development world, is used to refer to objects that use inheritance to create other objects. You generally have a top level object or interface which defines some properties which will always be part of an object. So for the classic example of Animal you would probably have something like the following:

public class Animal {
    private String name;
    private String diet;
}


public class Bird extends Animal {
    private long wingspan;
}

Then any object can either be an Animal or extend Animal to create and define more properties as shown above.

What is JSON?

JSON (JavaScript Object Notation) is a way of representing data and is fast becoming the defacto standard for sending data to web services or as way of sending data from one place to another. JSON has a particular format and can easily be generated either by hand typing the data or by using one of the many libraries that can help you to produce properly formatted JSON of your specific object. For this particular project I am using the Jackson 2 library https://github.com/FasterXML/jackson.

Creating JSON is often referred to a process known as serialization, where you basically serialize (convert) the data to a human readable output; in this case JSON. There are many different ways to handle serialisation of data to JSON and many different ways of embedding objects in the JSON. The problem comes when you wish to deserialize the JSON, convert the JSON back to your object.

The Problem and the Solution

My problem is a simple one how to provide a value in the serialized JSON output that would allow automatic de-serialization to the correct sub object (polymorphic object). After a lot of time spent searching and reading on the internet, I came across the following blog http://programmerbruce.blogspot.co.uk/2011/05/deserialize-json-with-jackson-into.html which lists a few possible methods. This got me experimenting and trying different solutions but still wasn’t giving me the desired output I wanted.

More searching led me to this question on stackoverflow http://stackoverflow.com/questions/14038084/json-nest-class-data-binding which describes how to bind the class values of polymorphic subtypes and how to serailiaze and deserailize the JSON.

The output below shows how the serialized object could look. The class name including the package name is added to the JSON output. When you come to deseralize the JSON data the Jackson processor looks for the value ‘type’ and uses that to select the correct object to deserialize to.

{
"type": "com.test.Bird", 
  "animal" : {
    "name": "bird"
  }
}

The java code for this is quite simple. Instead of adding your annotation to the top of the class you simply add this to the set Method used to add your Object. In this case it would look like the following:

public class Container 
{
  ...
   private Animal animal;

  ...

   public Animal getAnimal()
   {
      return animal;
   }

   @JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.EXTERNAL_PROPERTY, property="type")
   public void setAnimal(Animal animal)
   {
      this.animal = animal;
   }
}

This is extremely simple and can be customised yet still by changing the values used in the above annotations. If you want more customisation you could create your own deserailizer but that is beyond the scope of this blog.

I hope this helps in understanding the process a little better as there is little documentation beyond the basics in the Jackson docs.

Add new comment

This used to notify you of changes to the post or comment and optionally signup to the mailing list

Filtered HTML

  • Allowed HTML tags: <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
CAPTCHA
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.
Image CAPTCHA
Enter the characters shown in the image.
By submitting this form, you accept the Mollom privacy policy.