Java Gson Serialization and Deserialization with JSON

By Arvind Rai, July 23, 2014
In this page, we will learn Serialization and Deserialization between JSON and Java Object for special cases where Gson cannot simply understand class type of format of field. There are different type of cases as below which will be discussed in this page.

1. Dealing with Generic class as Gson has no idea what class type of class has passed.
2. Handling different format of a field in the class in Serialization and Deserialization like Date.
3. Creation of object for a class by Gson whose default constructor is not available.

Google Gson provides methods and interfaces to deal with the above situation. We will go through these API in detail for its use. To resolve google Gson JAR, visit the link Java Gson + JSON Tutorial with Examples

Serialization and Deserialization of Generic Types using Gson TypeToken

If a java class is generic type and we are using it with google Gson to JSON serialization and deserilization, Gson has no way to know what type of class has been passed to generic class. To fix this problem, Gson introduced TypeToken. Create Gson TypeToken class and pass the class type. Using this Type, Gson will be able to know the class passed in generic class. Now for the demo, find a generic class as Person.
Person.java
package com.concretepage.gson;
public class Person <T> {
    private T ob;
	public T getOb() {
		return ob;
	}
	public void setOb(T ob) {
		this.ob = ob;
	}
} 
Find Address class which will be used to pass to Person class.
Address.java
package com.concretepage.gson;
public class Address {
    private String city;
    private String zip;
	public String getCity() {
		return city;
	}
	public void setCity(String city) {
		this.city = city;
	}
	public String getZip() {
		return zip;
	}
	public void setZip(String zip) {
		this.zip = zip;
	}
} 
Now find the example for serialization and deserialization of Generic Types.
GenericTypeSeDe.java
package com.concretepage.gson;
import java.lang.reflect.Type;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
public class GenericTypeSeDe {
	public static void main(String[] args) {
		   Gson gson = new Gson();
		   //Serialization in JSON string
		   System.out.println("---Serialization in JSON string---");
		   Address address = new Address();
		   address.setCity("Varansi");
		   address.setZip("11111");
		   Person<Address> person = new Person<Address>();
		   person.setOb(address);
		   Type type = new TypeToken<Person<Address>>() {}.getType();
		   String json = gson.toJson(person, type);
		   System.out.println(json);
		   // Deserialization  in java Object
		   System.out.println("---Deserialization  in java Object---");
		   Person<Address> p = gson.fromJson(json, type);
		   Address add = (Address)p.getOb();
		   System.out.println(add.getCity());
		   System.out.println(add.getZip());
	}
} 
Find the output.
---Serialization in JSON string---
{"ob":{"city":"Varansi","zip":"11111"}}
---Deserialization  in java Object---
Varansi
11111

Gson Custom Serialization and Deserialization

The class which is going to participate in Gson Serialization and Deserialization, may have some fields whose format matters. Suppose if there is a date field in our class, it can have different format. Google Gson provides custom serialization and deserialization to deal with such situation.

I am using a class named as Item that will participate in custom serialization and deserialization which has no default constructor and this class has date field.
Item.java
package com.concretepage.gson;
import java.util.Date;
public class Item {
	private int id;
	private Date purchaseDate;
	public Item(int id){
		this.id = id;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public Date getPurchaseDate() {
		return purchaseDate;
	}
	public void setPurchaseDate(Date purchaseDate) {
		this.purchaseDate = purchaseDate;
	}
} 

Custom Serialization using Gson JsonSerializer

To create a custom serialization class, we need to create our own class which will implement Gson JsonSerializer and define serialize method. Gson. toJson() method uses this class in JSON serialization
DateSerializer.java
package com.concretepage.gson;
import java.lang.reflect.Type;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
public class DateSerializer implements JsonSerializer {
	  public JsonElement serialize(Date date, Type typeOfSrc, JsonSerializationContext context) {
		SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy");  
	    return new JsonPrimitive(sdf.format(date));
	  }
}  
Register this class with Gson instance as below.
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Date.class, new DateSerializer()); 

Custom Deserialization using Gson JsonDeserializer

To create a custom deserialization class, we need to create our own class which will implement Gson JsonDeserializer and define deserialize method. Gson. fromJson() uses this class while deserialization from JSON to java object.
DateDeserializer.java
package com.concretepage.gson;
import java.lang.reflect.Type;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
public class DateDeserializer implements JsonDeserializer<Date> {
	  public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) {
		    SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy");
		    Date date = null;
		    try {
			  date = sdf.parse(json.getAsJsonPrimitive().getAsString());
			  return date;
		    } catch (ParseException e) {
				e.printStackTrace();
		    }
		    return date;
         }
} 
Register this class with Gson instance .
gsonBuilder.registerTypeAdapter(Date.class, new DateDeserializer()); 

Instance Creator using Gson InstanceCreator

If a class which is going to participate in serialization and deserialization then that class should have a constructor with no arguments. So while deserialization, Gson API will be able to create the object. But if no such constructor is available in the class, the Gson has provided InstanceCreator that will be implemented by our class.
ItemInstanceCreator.java
package com.concretepage.gson;
import java.lang.reflect.Type;
import com.google.gson.InstanceCreator;
public class ItemInstanceCreator implements InstanceCreator {
	public Item createInstance(Type type) {
	    return new Item(0);
	}
} 
Register instance class with Gson instance.
gsonBuilder.registerTypeAdapter(Item.class, new ItemInstanceCreator()); 

Class with Main Method to Test Custom Serialization and Deserialization

Now find the class to test Gson custom serialization and deserialization.
CustomSeDe.java
package com.concretepage.gson;
import java.text.ParseException;
import java.util.Date;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class CustomSeDe {
	public static void main(String[] args) throws ParseException {
		GsonBuilder gsonBuilder = new GsonBuilder();
		gsonBuilder.registerTypeAdapter(Date.class, new DateSerializer());
		gsonBuilder.registerTypeAdapter(Date.class, new DateDeserializer());
		gsonBuilder.registerTypeAdapter(Item.class, new ItemInstanceCreator());
		Gson gson = gsonBuilder.create();
		Item item = new Item(0);
		item.setId(1);
		item.setPurchaseDate(new Date());
		//Serialization
		System.out.println("---Serialization---");
		String json = gson.toJson(item);
		System.out.println(json);
		//Deserialization
		System.out.println("---DeSerialization---");
		Item it = gson.fromJson(json, Item.class);
		System.out.println(it.getId());
		System.out.println(it.getPurchaseDate());
	}
} 
Find the output.
---Serialization---
{"id":1,"purchaseDate":"23-Jul-2014"}
---DeSerialization---
1
Wed Jul 23 00:00:00 IST 2014
POSTED BY
ARVIND RAI
ARVIND RAI







©2024 concretepage.com | Privacy Policy | Contact Us