gson

Getting started with gson

Remarks#

Gson is an Open Source Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object.

Goals for Gson

  • Provide easy to use mechanisms like toString() and constructor (factory method) to convert Java to JSON and vice-versa

  • Allow pre-existing unmodifiable objects to be converted to and from JSON

  • Allow custom representations for objects

  • Support arbitrarily complex objects

  • Generate compact and readable JSON output

Source code of Gson is available on Github.

User guide

Installation

In order to use Gson you have to include it in your project. You can do this by adding the following dependency of the Gson version available in Maven Central:

Maven

Add to pom.xml

<dependencies>
    <dependency>
      <groupId>com.google.code.gson</groupId>
      <artifactId>gson</artifactId>
      <version>2.8.0</version>
      <scope>compile</scope>
    </dependency>
</dependencies>

Gradle:

Add to build.gradle

compile 'com.google.code.gson:gson:2.8.0'

Serialization and deserialization

Gson gson = new Gson(); //Create a Gson object
MyType target = new MyType(); //This is the object you want to convert to JSON   
String json = gson.toJson(target); // serializes target to Json
MyType target2 = gson.fromJson(json, MyType.class); // deserializes json into target2

Arrays

JSON:

[
  {
    "id": 8484,
    "name": "David",
    "height": 173.2,
    "weight": 75.42
  },
  {
    "id": 8485,
    "name": "Ronald",
    "height": 183.73,
    "weight": 83.1
  }
]

Person.java

public class Person {
    public int id;
    public String name;
    public double height;
    public double weight;

    @Override
    public String toString() {
        return "[ id: " + String.valueOf(id) + ", name: " + name + ", height: " + String.valueOf(height) + ", weight: " + String.valueOf(weight) + " ]";
    }
}

Usage:

Gson gson = new Gson();
Person[] persons = gson.fromJson(json, Person[].class);
for(Person person : persons)
    System.out.println(person.toString());

Output:

[ id: 8484, name: David, height: 173.2, weight: 75.42 ]
[ id: 8485, name: Ronald, height: 183.73, weight: 83.1 ]

Simple Example

The Gson library provides Gson.class which handles all conversion between Java and JSON objects. An instance of this class can be created by invoking default constructor. You usually would like to have one Gson instance for the most part of operations in your program.

Gson gson = new Gson();

First, we need to create class of our object with which we will be working with

class Person {
   public String name;
   public int age;

   public Person(String name, int age){
       this.name = name;
       this.age = age;
   }
}

Gson class provides methods toJson and fromJson which are the main entry points for JSON and java objects

Let’s try to convert java object to JSON and back to java object

Person person = new Person("Jason", 29);
//using gson object which we created earlier
String json = gson.toJson(person);
System.out.println(json);
//Outputs: {"name": "Jason", "age": 29}

And now back again

String json = "{\"name\": \"Jason\", \"age\": 29}";
Person person = gson.fromJson(json, Person.class);
System.out.println(person.age + "yo " + person.name + " walks into a bar");
//Outputs "29 yo Jason walks into a bar"

Convert String to JsonObject without POJO

String jsonStr = "{\"name\" : \"Abcd\", \"greeting\": \"Hello\", }"; //Sample Json String

Gson gson = new Gson(); // Creates new instance of Gson
JsonElement element = gson.fromJson (jsonStr, JsonElement.class); //Converts the json string to JsonElement without POJO 
JsonObject jsonObj = element.getAsJsonObject(); //Converting JsonElement to JsonObject

String name = jsonObj.get("name").getAsString(); //To fetch the values from json object
String greeting = jsonObj.get("greeting").getAsString();

Using GSON with inheritance

GSON does not support inheritance our of the box. Let’s say we have the following class hierarchy:

public class BaseClass {
    int a;
 
    public int getInt() {
        return a;
   }
}
 
public class DerivedClass1 extends BaseClass {
     int b;
 
     @Override
     public int getInt() {
         return b;
     }
 }
 
public class DerivedClass2 extends BaseClass {
    int c;
 
    @Override
    public int getInt() {
        return c;
    }
}

And now we want to serialize an instance of DerivedClass1 to a json string

DerivedClass1 derivedClass1 = new DerivedClass1();
derivedClass1.b = 5;
derivedClass1.a = 10;
 
Gson gson = new Gson();
String derivedClass1Json = gson.toJson(derivedClass1);

Now, in another place, we receive this json string and want to deserialize it - but in compile time we only know it is supposed to be an instance of BaseClass:

BaseClass maybeDerivedClass1 = gson.fromJson(derivedClass1Json, BaseClass.class);
System.out.println(maybeDerivedClass1.getInt());

But GSON does not know derivedClass1Json was originally an instance of DerivedClass1, so this will print out 10.

How to solve this?

You need to build your own JsonDeserializer, that handles such cases. The solution is not perfectly clean, but I could not come up with a better one.

First, add the following field to your base class

@SerializedName("type")
private String typeName;
 

And initialize it in the base class constructor

public BaseClass() {
    typeName = getClass().getName();
}

Now add the following class:

public class JsonDeserializerWithInheritance<T> implements JsonDeserializer<T> {
 
 @Override
 public T deserialize(
     JsonElement json, Type typeOfT, JsonDeserializationContext context)
     throws JsonParseException {
     JsonObject jsonObject = json.getAsJsonObject();
     JsonPrimitive classNamePrimitive = (JsonPrimitive) jsonObject.get("type");
 
     String className = classNamePrimitive.getAsString();
 
     Class<?> clazz;
     try {
     clazz = Class.forName(className);
     } catch (ClassNotFoundException e) {
     throw new JsonParseException(e.getMessage());
     }
     return context.deserialize(jsonObject, clazz);
 }
}
 

All there is left to do is hook everything up -

GsonBuilder builder = new GsonBuilder();
 builder
 .registerTypeAdapter(BaseClass.class, new JsonDeserializerWithInheritance<BaseClass>());
 Gson gson = builder.create();
 

And now, running the following code-

 DerivedClass1 derivedClass1 = new DerivedClass1();
 derivedClass1.b = 5;
 derivedClass1.a = 10;
 String derivedClass1Json = gson.toJson(derivedClass1);
 
 BaseClass maybeDerivedClass1 = gson.fromJson(derivedClass1Json, BaseClass.class);
 System.out.println(maybeDerivedClass1.getInt());

Will print out 5.


This modified text is an extract of the original Stack Overflow Documentation created by the contributors and released under CC BY-SA 3.0 This website is not affiliated with Stack Overflow