Tech and Media Labs
This site uses cookies to improve the user experience.




GSON - Gson

Jakob Jenkov
Last update: 2016-02-18

GSON is Google's JSON parser and generator for Java. Google developed GSON for internal use but open sourced it later. GSON it reasonably easy to use, but in my opinion not as elegant as Jackson or Boon (the winner in my opinion). In this GSON tutorial I will take you through how to use GSON to parse JSON into Java objects, and serialize Java objects into JSON.

GSON contains multiple APIs which you can use to work with JSON. This tutorial covers the Gson component which parses JSON into Java objects, or generates JSON from Java objects. In addition to the Gson component GSON also has a pull parser in the GSON JsonReader component.

Before you can use GSON you must first install GSON in your Java project. I have explained that in its own text about GSON Installation .

Creating a Gson Instance

Before you can use GSON you must first create a new Gson object. There are two ways to create a Gson instance:

  • Using new Gson()
  • Creating a GsonBuilder instance and calling create() on it.

Both of these ways to create a Gson instance will be covered in this GSON tutorial.

new Gson()

You can create a Gson object simply by creating it with the new Gson() instruction. Here is how creating a Gson object looks:

Gson gson = new Gson();

Once you have created a Gson instance you can start using it to parse and generate JSON.

GsonBuilder.build()

Another way to create a Gson instance is to create a GsonBuilder() and call its create() method. Here is an example of creating a GsonBuilder and calling create():

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

Using a GsonBuilder allows you to set configuration options on the GsonBuilder before creating the Gson object. You will see examples of this later in this GSON tutorial.

Parsing JSON Into Java Objects

GSON can pase JSON into Java objects using the fromJson() method of the Gson object. Here is an GSON example of parsing JSON into a Java object:

String json = "{\"brand\":\"Jeep\", \"doors\": 3}";

Gson gson = new Gson();

Car car = gson.fromJson(json, Car.class);

The first line of the example defines the JSON string to parse. The second line creates a Gson instance. The third line calls the gson.fromJson() method which parses the JSON string into a Car object.

The first parameter to fromJson() is the JSON source. In the example above the JSON source is a string. The second parameter to the fromJson() method is the Java class to parse parse the JSON into an instance of. The Gson instance creates an instance of this class and parses the JSON into it. Thus you should make sure that this class has a no-arg constructor, or GSON cannot use it.

Here is how the Car class looks:

public class Car {
    public String brand = null;
    public int    doors = 0;
}

Generating JSON From Java Objects

GSON can also generate JSON from Java objects. You do so via the Gson object. To generate JSON you call the toJson() method of the Gson object. Here is an example of generating JSON from a Java object with GSON:

Car car = new Car();
car.brand = "Rover";
car.doors = 5;

Gson gson = new Gson();

String json = gson.toJson(car);

Pretty Printing

By default the Gson instance created with new Gson() prints (generates) as compact as possible JSON. Here is an example of the compact JSON output from a default Gson instance:

{"brand":"Rover","doors":5}

However, this compact JSON can be hard to read. Therefore GSON offers a pretty printing option where the JSON is printed so it is more readable in a text editor. Here is an example of how to create a Gson instance with pretty print enabled:

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

Here is an example of how the same JSON would look pretty printed:

{
  "brand": "Rover",
  "doors": 5
}

Excluding Fields

You can tell GSON to exclude fields from your Java classes from being serialized. There are several ways to tell GSON to exclude a field. The following sections of GSON tutorial will look at the most useful and easy to use ways to exclude fields.

Transient Fields

If you make a field in a Java class transient then GSON will ignore it in both serialization and deserialization. Here is how the Car class from earlier looks with the brand field marked as transient:

public class Car {
    public transient String brand = null;
    public int    doors = 0;
}

The @Expose Annotation

The GSON @Expose annotation (com.google.gson.annotations.Expose) can be used to mark a field to be exposed or not (included or not) when an object is serialized or deserialized. The @Expose annotation can take two parameters. Each parameter is a boolean which can take either the value true or false. Here are some GSON @Expose annotation examples to show what I mean:

@Expose(serialize = true);
@Expose(serialize = false);
@Expose(deserialize = true);
@Expose(deserialize = false);
@Expose(serialize = true , deserialize = false);
@Expose(serialize = false, deserialize = true);

The @Expose annotation's serialize parameter specifies if the field annotated with the @Expose annotation should be included when the owning object is serialized. The deserialize parameter specifies whether that field should be read when the owning object is deserialized.

Here is an example class using the GSON @Expose annotation:

public class Car {

    @Expose(serialize = false, deserialize = false)
    public String brand = null;

    @Expose(serialize = true, deserialize = true)
    public int    doors = 0;
}

Notice the @Expose annotation above the fields, telling whether the given field should be included when serialized or deserialized.

In order to get GSON to react to the @Expose annotations you must create a Gson instance using the GsonBuilder class. Here is how that looks:

GsonBuilder builder = new GsonBuilder();
builder.excludeFieldsWithoutExposeAnnotation();
Gson gson = builder.create();

Note, that this configuration makes GSON ignore all fields that do not have an @Expose annotation. To have a field included in serialization or deserialization it must have an @Expose annotation above it.

GsonBuilder.setExclusionStrategies()

Another way to exclude a field of a class from serialization or deserialization in GSON is to set an ExclusionStrategy on a GsonBuilder, and use that GsonBuilder to build the Gson object with.

ExclusionStrategy is an interface, so you will have to create a class that implements the ExclusionStrategy interface. Here is an example that implements the ExclusionStrategy interface with an anonymous class:

ExclusionStrategy exclusionStrategy = new ExclusionStrategy() {
    public boolean shouldSkipField(FieldAttributes fieldAttributes) {
        if("brand".equals(fieldAttributes.getName())){
            return true;
        }
        return false;
    }

    public boolean shouldSkipClass(Class aClass) {
        return false;
    }
};

Notice that inside the shouldSkipField() method of the ExclusionStrategy implementation the example checks if the given field name is brand. If it is, that field is excluded from serialization and deserialization.

To use the ExclusionStrategy implementation create a GsonBuilder and set the ExclusionStrategy on it using the setExclusionStrategies() method, like this:

GsonBuilder builder = new GsonBuilder();
builder.setExclusionStrategies(exclusionStrategy);

Gson gson = builder.create();

The exclusionStrategy variable has to point to an implementation of the ExclusionStrategy interface.

Serializing Null Fields

By default the Gson object does not serialize fields with null values to JSON. If a field in a Java object is null, Gson excludes it.

You can force Gson to serialize null values via the GsonBuilder. Here is an example showing how to force serialization of null values with GSON:

GsonBuilder builder = new GsonBuilder();

builder.serializeNulls();

Gson gson = builder.create();

Car car = new Car();
car.brand = null;

String json = gson.toJson(car);
System.out.println(json);

Notice the call to serializeNulls() on the GsonBuilder instance before creating the Gson object. Once serializeNulls() has been called the Gson instance created by the GsonBuilder will include null fields in the serialized JSON.

The output from the above example would be:

{"brand":null,"doors":0}

Notice how the brand field is null.

Custom Instance Creators in GSON

By default GSON will try to create an instance of a given class by calling the no-arg constructor of that class. However, if a given class does not have a default constructor, or you want to do some default configuration of the instance, or if you want to create an instance of a subclass instead, you need to create and register your own instance creator.

A GSON instance creator is simply an object factory. An instance creator has to implement the InstanceCreator interface (com.google.gson.InstanceCreator). Here is an example InstanceCreator implementation:

import com.google.gson.InstanceCreator;

public class CarCreator implements InstanceCreator<Car> {
    public Car createInstance(Type type) {
        Car car = new Car();
        car.brand = "Toyota";
        return car;
    }
}

You use the above CarCreator class by registering it on a GsonBuilder before you create the Gson instance. Here is an example:

GsonBuilder gsonBuilder = new GsonBuilder();

gsonBuilder.registerTypeAdapter(Car.class, new CarCreator());

Gson gson  = gsonBuilder.create();

Now the Gson instance will use the CarCreator instance to create Car instances. You can prove that to yourself by running this code (after the CarCreator has been registered):

String carJson = "{ \"doors\" : 4 }";

Car car = gson.fromJson(carJson, Car.class);

System.out.println(car.brand);

The default brand property value is null and the JSON string does not contain a brand property. Therefore you will see the value for the brand property set inside the CarCreator's createInstance() method (Toyota).

Version Support in GSON

GSON contains simple version support for the Java objects it reads and writes. GSON version support means that you can mark fields in your Java classes with a version number, and then have GSON include or exclude fields from your Java classes based on their version number.

To use GSON version support you must first annotate your Java classes with the GSON @Since annotation. Here is an example Person class with its fields annotated with the @Since annotation:

import com.google.gson.annotations.Since;

public class Person {

    @Since(1.0)
    public String firstName = null;

    @Since(1.0)
    public String lastName = null;

    @Since(2.0)
    public String middleName = null;

    @Since(3.0)
    public String email = null;
}

Second, you must create a GsonBuilder and tell it what version it should be serializing to and deserializing from. Here is an example of how you create a GsonBuilder and set the version number on it:

GsonBuilder builder = new GsonBuilder();
builder.setVersion(2.0);

Gson gson = builder.create();

The Gson instance created from the above GsonBuilder will now just include fields that are annotated with @Since(2.0) or a lower version number than 2.0 . In the Person example class above that means the fields firstName, lastName and middleName. The email field is annotated with version 3.0 which is later than 2.0, so GSON will exclude the email field.

Here is an example of serializing a Person object to JSON and look at the generated JSON:

Person person     = new Person();
person.firstName  = "John";
person.lastName   = "Doe";
person.middleName = "Blocks";
person.email      = "john@doe.com";

GsonBuilder builder = new GsonBuilder();
builder.setVersion(2.0);

Gson gson = builder.create();

String personJson = gson.toJson(person);

System.out.println(personJson);

This example will print out the following JSON string:

{"firstName":"John","lastName":"Doe","middleName":"Blocks"}

Notice how GSON excluded the email field in the generated JSON.

Excluding fields based on version works the same for reading JSON into Java objects (deserialization). Look at the following JSON string which contains all the fields, including the email field:

"{\"firstName\":\"John\",\"lastName\":\"Doe\",\"middleName\":\"Blocks\",\"email\":\"john@doe.com\"}"

If you were to read a Person object with the above Gson object, the email field will not be read even if it is present in the JSON string. Here is how reading a Person object with the above Gson instance would look:

String personJson2  = "{\"firstName\":\"John\",\"lastName\":\"Doe\",\"middleName\":\"Blocks\",\"email\":\"john@doe.com\"}";

Person personRead = gson.fromJson(personJson2, Person.class);

Custom Serialization and Deserialization

GSON offers the possibility for you to plug in customer serializers and deserializers. Your custom serializers can convert Java values to custom JSON, and your custom deserializers can convert custom JSON to Java values again.

Custom Serializer

A custom serializer in GSON has to implement the JsonSerializer interface. The JsonSerializer interface looks like this:

public interface JsonSerializer<T> {
    public JsonElement serialize(T value, Type type,
        JsonSerializationContext jsonSerializationContext) {
    }
}

Implementing a custom serializer that can serializer boolean values looks like this:

public class BooleanSerializer implements JsonSerializer<Boolean> {

  public JsonElement serialize(Boolean aBoolean, Type type,
    JsonSerializationContext jsonSerializationContext) {
    if(aBoolean){
       return new JsonPrimitive(1);
    }
      return new JsonPrimitive(0);
  }
}

Notice how the T type parameter is replaced with the Boolean class in two places.

Inside the serialize() method you can convert the value (a Boolean in this cas) to a JsonElement which the serialize() method is required to return. In the example above we use a JsonPrimitive which is also a JsonElement. As you can see, boolean values of true are converted to 1 and false to 0, instead of true and false normally used in JSON.

Registering this custom serializer is done like this:

GsonBuilder builder = new GsonBuilder();

builder.registerTypeAdapter(Boolean.class, new BooleanSerializer()) ;

Gson gson = builder.create();

It is the call to registerTypeAdapter() which registers the customer serializer with GSON.

Once registered, the Gson instance created from the GsonBuilder will use the custom serializer. To see how that works we will use the following POJO class:

public class PojoWithBoolean {

    public String username = null;
    public Boolean isSuperUser = false;
}

Here is how serializing a PojoWithBoolean instance looks:

PojoWithBoolean pojo = new PojoWithBoolean();
pojo.username = "abc";
pojo.isSuperUser = false;

String pojoJson = gson.toJson(pojo);

System.out.println(pojoJson);

The output printed from this example would be:

{"username":"abc","isSuperUser":0}

Notice how the false value of isSuperUser is converted to a 0.

Custom Deserializer

GSON also provides support for custom deserializers. A custom deserializer must implement the JsonDeserializer interface. The JsonDeserializer interface looks like this:

public interface JsonDeserializer<T> {
    
    public Boolean deserialize(JsonElement jsonElement, 
        Type type, JsonDeserializationContext jsonDeserializationContext) 
        throws JsonParseException;

}

Implementing a custom deserializer for the Boolean type would look like this:

public class BooleanDeserializer implements JsonDeserializer<Boolean> {

    public Boolean deserialize(JsonElement jsonElement, Type type,
    JsonDeserializationContext jsonDeserializationContext)
    throws JsonParseException {

        return jsonElement.getAsInt() == 0 ? false : true;
    }
}

Registering the custom deserializer with GSON is done using another version of the registerTypeConverter() method. Here is how registering the above deserializer with GSON looks:

GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(Boolean.class, new BooleanDeserializer());

Gson gson = builder.create();

And here is how parsing a JSON string with the created Gson instance looks:

String jsonSource = "{\"username\":\"abc\",\"isSuperUser\":1}";

PojoWithBoolean pojo = gson.fromJson(jsonSource, PojoWithBoolean.class);

System.out.println(pojo.isSuperUser);

The output printed from this GSON custom deserializer example would be:

true

... since the 1 in the JSON string would be converted to the boolean value true .

Jakob Jenkov




Copyright  Jenkov Aps
Close TOC