Gson Tutorial: Read and Write JSON with Examples

All modern applications generally fetch data from remote services (e.g. REST or SOAP) that are mostly either XML or JSON format. Gson helps applications in Java-JSON serialization and deserialization automatically as well as manually, if needed, using simple toJson() and fromJson() methods.

  • Gson can work with arbitrary Java objects including pre-existing objects that we do not have source code of.
  • The best benefit of Gson is that it does not make it mandatory to add annotations into Java classes until we are doing something very specific for certain member fields.
  • Note that the Gson instance does not maintain any state while invoking JSON operations. It makes the Gson instance to be thread-safe. So, we are free to reuse the same object for multiple JSON serialization and deserialization operations.
Gson gson = new Gson();

// POJO -> JSON String
String json = gson.toJson(new User(1, "Lokesh"));

// JSON String -> POJO 
User user = gson.fromJson(json, User.class);

1. Maven

Refer to the latest version of Gson from its Maven repo page.

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.9.0</version>
</dependency>

The Gradle dependency is as follows:

dependencies {
  implementation 'com.google.code.gson:gson:2.9.0'
}

2. Creating the Gson Instance

2.1. Using Default Constructor

The most straightforward way to have a Gson instance is to call its default empty constructor. It creates the Gson instance with the following default configurations:

  • Generates compact JSON representations by removing all the unneeded whitespaces.
  • Omits all the fields that are null. The nulls in arrays are kept as is.
  • Uses the default Date format is the same as DateFormat.DEFAULT that ignores the millisecond portion.
  • Excludes transient or static fields from consideration for serialization and deserialization.
  • Ignores @Expose and @Since annotations.
Gson gson = new Gson();

2.2. Using GsonBuilder

To override the default configuration, we can use the GsonBuilder class. After calling its constructor, we can call its various configuration methods and finally call create() to get the Gson instance.

Gson gson = new GsonBuilder()
     .registerTypeAdapter(Id.class, new IdTypeAdapter())
     .enableComplexMapKeySerialization()
     .serializeNulls()
     .setDateFormat(DateFormat.LONG)
     .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
     .setPrettyPrinting()
     .setVersion(1.0)
     .create();

3. Read and Write JSON

3.1. Convert Java Object to JSON String

To convert a Java object to a JSON string, use the Gson instance to call the function toJson() and pass the object.

Gson gson = new Gson();

User user = new User();
String json = gson.toJson(user);

3.2. Convert JSON String to Java Object

Similarly, to convert the JSON string to a Java object, use the fromJson() method.

String json = ...;
Gson gson = new Gson();

User user = gson.fromJson(json, User.class);

4. Gson InstanceCreator – When No-args Constructor is not Present

In most cases, Gson library is smart enough to create instances even if any class does not provide a default no-args constructor. But, if we find any problem using a class that does not contain no-args constructor, we can use InstanceCreator support. You need to register the InstanceCreator of a java class type with Gson first before using it.

For example, Department does not have any default no-arg constructor.

public class Department {

   public Department(String deptName){
      this.deptName = deptName;
   }

   private String deptName;

   //Settes, getters and toString()
}

And our Employee class has a reference of Department as:

public class Employee {

   private Integer id;
   private String firstName;
   private String lastName;
   private List<String> roles;
   private Department department; //Department reference
    
   //Other setters and getters
}

To use Department class correctly, we need to register an InstanceCreator for Department as below:

class DepartmentInstanceCreator implements InstanceCreator<Department> {
   public Department createInstance(Type type)
   {
      return new Department("None");
   }
}

Now use the above InstanceCreator as below.

GsonBuilder gsonBuilder = new GsonBuilder();
 
gsonBuilder.registerTypeAdapter(Department.class, new DepartmentInstanceCreator());
 
Gson gson = gsonBuilder.create();
 
System.out.println(
            gson.fromJson("{'id':1,'firstName':'Lokesh','lastName':'Gupta',
            'roles':['ADMIN','MANAGER'],'department':{'deptName':'Finance'}}", 
            Employee.class));

Program output:

Employee [id=1, firstName=Lokesh, lastName=Gupta, roles=[ADMIN, MANAGER], department=Department [deptName=Finance]]

5. Custom Serialization and Deserialization

We often need to write/read the JSON values which are not the default representation of the Java object. In that case, we need to write a custom serializer and deserializer of that Java type.

In our example, I am writing a serializer and deserializer for java.util.Date class, which will help write the Date format in “dd/MM/yyyy” format.

5.1. Custom Serializer

The following DateSerializer class allows us to control the serialization process when converting java.util.Date objects to JSON representation.

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<Date> {

   private static final SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");

   public JsonElement serialize(Date date, Type typeOfSrc, JsonSerializationContext context) {
      return new JsonPrimitive(dateFormat.format(date));
   }
}

5.2. Custom Deserializer

The following DateDeserializer class customizes the process of converting JSON representations into Date objects.

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> {

   private static final SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");

   public Date deserialize(JsonElement dateStr, Type typeOfSrc, JsonDeserializationContext context) {
      try {
         return dateFormat.parse(dateStr.getAsString());
      } 
      catch (ParseException e) {
         e.printStackTrace();
      }
      return null;
   }
}

5.3. Usage

Now you can register above serializer and deserializer classes with GsonBuilder as below:

GsonBuilder gsonBuilder = new GsonBuilder();

gsonBuilder.registerTypeAdapter(Date.class, new DateSerializer());
gsonBuilder.registerTypeAdapter(Date.class, new DateDeserializer());

6. Pretty Printing the Formatted JSON

The default JSON output that is provided by Gson is a compact JSON format. This means that there will not be any white-space in the output JSON structure. To generate a more readable and pretty-looking JSON use GsonBuilder.setPrettyPrinting().

Gson gson = new GsonBuilder().setPrettyPrinting().create();

String jsonOutput = gson.toJson(employee);

Program output:

{
  "id": 1,
  "firstName": "Lokesh",
  "lastName": "Gupta",
  "roles": [
    "ADMIN",
    "MANAGER"
  ],
  "birthDate": "17/06/2014"
}

7. Versioning Support with @Since

This is an excellent feature you can use, if the class file you are working on has been modified in different versions and fields have been annotated with @Since. All you need to do is to use setVersion() method of GsonBuilder.

GsonBuilder gsonBuilder = new GsonBuilder();
 
gsonBuilder.registerTypeAdapter(Date.class, new DateSerializer());
gsonBuilder.registerTypeAdapter(Date.class, new DateDeserializer());
 
//Specify the version like this
gsonBuilder.setVersion(1.0);
 
Gson gson = gsonBuilder.create();

The following is an example of fields added in various versions in Employee.java.

public class Employee
{
   @Since(1.0)
   private Integer id;
   private String firstName;
   private String lastName;
    
   @Since(1.1)
   private List<String> roles;
    
   @Since(1.2)
   private Date birthDate;
    
   //Setters and Getters
}

Let us see an example of serialization with versioning support.

//Using version 1.0 fields
gsonBuilder.setVersion(1.0);
 
Output:
{"id":1,"firstName":"Lokesh","lastName":"Gupta"}
 
/////////////////////////////////////////////////////////////
 
//Using version 1.1 fields
gsonBuilder.setVersion(1.1);
 
Output:
{"id":1,"firstName":"Lokesh","lastName":"Gupta","roles":["ADMIN","MANAGER"]}
 
/////////////////////////////////////////////////////////////
 
//Using version 1.2 fields
gsonBuilder.setVersion(1.2);
 
Output:
{"id":1,"firstName":"Lokesh","lastName":"Gupta","roles":["ADMIN","MANAGER"],"birthDate":"17/06/2014"}

8. Gson Fundamentals

In this first part, we will learn about the Google Gson library and its basic mapping functionality.

  • Getting Started Guide – Learn to use GSON to serialize a simple Java Object into the JSON representation and to deserialize the JSON string to an equivalent Java object.
  • Compact Vs. Pretty Printing for JSON Output Format – The default JSON output that is provided by Gson is a compact JSON format. Use the Pretty Print feature to format the JSON for reading purposes.
  • Mapping of Arrays and Lists of Objects – Learn to use Google GSON library to deserialize or parse JSON, containing JSON arrays, to Java arrays or List objects.
  • Mapping of Sets – Learn to use Google GSON library to deserialize or parse JSON to Set (e.g. HashSet) in java.
  • Mapping of Maps – Learn to serialize HashMap using Google Gson library. Also, learn to deserialize JSON strings to HashMap containing custom Objects using Gson such that field values are copied into appropriate generic types.

9. Advance Usage

The basic examples in the first part are good enough for default usecases. We may need to customize the behavior of Gson to support specific requirements. Learn how to do this.

Drop me your questions related to this gson tutorial.

Happy Learning !!

Download Sourcecode

Comments

Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.