JSON is a lightweight language independent data-interchange format which is one of the common ways of encoding data over HTTP. This articles goes over the use of the Jackson library to serialize and deserialize Java object to JSON.

Project Setup

If you have not already done so download and install a latest copy of the JDK. Also download the latest Jackson Jar file. Create a folder with the jar file, and a few classes you want to serialize. I created ParentClass.java, Child1.java and Child 2.java.

Parent.java

The excerpt below shows the contents of Parent.java, note that we are annotating the class to help with serialization. The "JsonTypeInfo" annotation tells jackson to encode the object type in the resulting JSON output in a field called objectType. Further we are also defining the possible subtypes of Parent which any input JSON text could be serialized.

import org.codehaus.jackson.annotate.JsonSubTypes;
import org.codehaus.jackson.annotate.JsonTypeInfo;

@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="objectType")
@JsonSubTypes({

        @JsonSubTypes.Type(value=Child1.class),
        @JsonSubTypes.Type(value=Child2.class)
})
public class ParentClass {

}

 

Child1.java

The next snippet shows the Child1 class, we have also annotated the class to encode type but we do not need to define any sub-types. The class has two fields, one of which is annotated to be a JsonProperty and the other is marked to be ignored.

import org.codehaus.jackson.annotate.JsonTypeInfo;
import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.annotate.JsonIgnore;

@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="objectType")
public class Child1 extends ParentClass {

	@JsonProperty
	public int SerializeMe;

	@JsonIgnore
	public int dontSerialize me;

}

 

Child2.java

Child2 is very similar except for a few differences which highlight some of the features of Jackson, first we are able serialize more complex types such as the ArrayList of type string and second, we are also able to annotate Java Bean style getters to return a JSON property even if they have no member variable to back them.

import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.annotate.JsonTypeInfo;
import java.util.List;

@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="objectType")

public class Child2 extends ParentClass {

	@JsonProperty
	public List SerializeMe;

	@JsonProperty
	public int getSerializeMeToo() {
		return 53;
	}

	@JsonProperty
	public void setSerializeMeToo(int value) {
		//Do nothing
	}
}

 

Driver.java

Finally lets create a driver class to test our serialization and deserialization. For this we use the ObjectMapper class which has a writeValueAsString method. We just pass an annotated class to ObjectMapper's writeValueAsString method and get an encoded JSON string. Similarly we can use the readValue method to deserialize JSON back to a java object. As the code below shows we pass the string representation of JSON as well as an Ancestor of the object we are deserializing. Notice how we pass ParentClass to the readValue method but when print the class type out you will see it outputs "Child1" and "Child2" correctly.

import org.codehaus.jackson.map.ObjectMapper;
import java.util.Arrays;

public class Driver {

	public static void main(String[] args) {

		try {

			ObjectMapper oMapper = new ObjectMapper();
			Child1 child1 = new Child1();
			child1.SerializeMe = 10;
			child1.dontSerializeMe = 12;
			Child2 child2 = new Child2();
			child2.SerializeMe = Arrays.asList("1","2","3");
			String outputChild1 = oMapper.writeValueAsString(child1);
			String outputChild2 = oMapper.writeValueAsString(child2);
			System.out.println(outputChild1);
			System.out.println(outputChild2);

			ParentClass inputChild1 = oMapper.readValue(outputChild1, ParentClass.class);
			ParentClass inputChild2 = oMapper.readValue(outputChild2, ParentClass.class);

			System.out.println(inputChild1.getClass().toString());
			System.out.println(inputChild2.getClass().toString());

		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

}

 

Compiling and running the code

#To compile the code fire up a terminal or the command line and enter the following command
javac -classpath jackson-all-1.8.4.jar:./ *.java

#To run the code run the following command:
java -classpath jackson-all-1.8.4.jar:./ Driver

#Your output should be something like:
{"objectType":"Child1","SerializeMe":10}

{"objectType":"Child2","SerializeMe":["1","2","3"],"serializeMeToo":53}

class Child1

class Child2

 

Notice the fact that the class name is added as a property to the output JSON, and how the dontSerializeMe field of Child1 is ignored. Also note that the types of the objects generated from JSON are Child1 and Child2 respectively even though we told the mapper we were looking for a ParentClass type.

Source Code

The source code shown here can be Downloaded Here

Note that all code and other source provided here are licensed under the BSD License.

Further Reading