Google GSON for JSON Processing

GSON is a very popular Java library for work with JSON.

JavaScript Object Notation (JSON) is a lightweight data exchange format. Like XML, JSON provides a way of representing object that is both human readable and machine processable.

JSON is the most commonly used data exchange format on the Web. In the Java ecosystem, several libraries which that you can use to serialize Java objects to JSON, transmit the JSON data over a network, and deserialize the JSON back to Java objects.

In this post, we’ll take a look at using the GSON library, which stands for Google JSON.

The Maven POM

In order to use GSON, you need the JAR files of the GSON library in your project classpath. If you are using Maven, include the GSON dependency in your Maven POM.

The code to add the GSON dependency is this:

The POJO

For the sample application, let’s create a Product POJO with few fields to represent product information.

Here is the code of the Product class.

Product.java

Converting Java Objects to JSON Representations

Before you start using GSON in your application, you need to first create an instance of Gson. There are two ways to do so:

  • Use the Gson class to create a new instance.
  • Create a GsonBuilder instance and call the create() method on it.

Use the GsonBuilder when you want to configure your Gson object. Otherwise, the Gson class will itself serve you.

Once you have a Gson object, you can call the toJson() method. This method takes a Java object and returns the corresponding JSON, as a String.

The following code shows how to covert the Product POJO into JSON.

Here is a unit test to test the simpleJSON() method.

Above, I am using JUnit as the test framework. If you are new to JUnit, I checkout my series of posts on Unit Testing using JUnit.

The output on running the test in IntelliJ is this.

JSON Serialization with GSON

For pretty printing of the JSON, using Gson use this code:

In the code above, the setPrettyPrinting() method on the GsonBuilder creates the Gson instance with pretty printing enabled.

The code to test the simpleJsonWithPrettyPrinting() method is this.

Here is the test output:
JSON Serialization with GSON with Preety Printing

Converting JSON Strings to Java Objects Using GSON

Gson also allows you to convert JSON data into Java objects.

Consider that you have the following JSON string:

You can parse this JSON string into a Product object using the fromJson() method of Gson as shown.

The first parameter of the fromJson() method is the source JSON that must be converted into Product. In our example it is the json variable of type String. The second parameter is the Product object (POJO) that will be initialized with the JSON.

Note: Ensure that the POJO to which the JSON is converted to has a no-argument constructor. This is required so that Gson can create an instance of this class.

The test code to test the jsonToObject() method is this.

Here is test output from the above unit test:

JSON Deserialization with GSON

Excluding Fields from being Serialized or Deserialized

At times you might not want certain fields of a POJO to be serialized or deserialized. GSON allows you to exclude such fields from your POJO.

One of the several ways of excluding fields is by using the transient keyword.

If you declare any field in the Java class as transient, Gson ignores it during both serialization and deserialization.

The code to declare a field as transient is this.

When you serialize the object to JSON, you will find that the version field of the POJO is not serialized.

To summarize, a field marked as transient ensures that it will neither be serialized nor deserialized.

However, at times you need more control. You might need that a field should be serialized but never deserialized, and vice-versa.

For such requirements, use the @Expose annotation of Gson. This annotation tells whether or not to include a field during either serialization, deserialization, or both. For example, using the @Expose annotation, you can tell that the version field should only be serialized, and not deserialized back. Similarly the other way around.

The @Expose annotation takes one, both, or none of the two elements: serialize and deserialize, both of which are of Boolean type.

The Product POJO fields after applying the @Expose annotation is this.

In this code, the imageUrl field is marked with the @Expose annotation with the serialize element set to false and deserialize set to true. Therefor the imageUrl field will only be deserialized from JSON, but will not be serialized.

The price field is marked with @Expose, and therefore by default, it’s both serialize and deserialize elements are set to true. Therefore the The price field will both be serialized and deserialized.

You need to explicitly tell Gson to use the @Expose annotation like this.

This code calls the excludeFieldsWithoutExposeAnnotation() method on the GsonBuilder object to exclude all fields without the @Expose annotation.

The test code is this:

The output of the test in IntelliJ is this.
JSON Serialization with GSON with Expose Fields

Custom Serialization and Deserialization

So far, we have converted JSON into Java object and vice versa using the default Gson implementation.

However, at times, you may want to configure the serialization and deserialization processes. For example, you might need to specifically map a particular POJO field with a JSON key having a different name.

To do so, you can use the JsonSerializer and JsonDeserializer interfaces.

Creating a Custom Serializer

Consider the following fields in a POJO that you need to serialize.

The POJO needs to be serialized to this JSON:

By default, Gson uses the field names as keys in the JSON. For example, the class has a field named productId, while the same field is represented as product-id in the required JSON.

To serialize the Java object into the expected JSON, you need to create a custom serializer class that implements the JsonSerializer interface. The code shows a custom serializer class.

The Type parameter of the JsonSerializer interface is the type of the object to be serialized.
Here an instance of Product is serialized.

The return type of the overridden serialize() method is a JsonElement. The JsonElement can be of four concrete types. One among them is JsonObject, a key-value pair where the value itself is a type of JsonElement.

To serialize the Product object, you need an instance of JsonElement. This example uses JsonObject. This object is populated with the fields as required in the JSON using the addProperty() method. Finally, the serialize() method returns the populated JsonObject.

To use this serializer, you need to register it through the GsonBuilder.

You can register and use the custom serializer, like this:

By registering the CustomProductSerializer class, you are telling Gson to use the custom serializer class whenever an object of Product class is serialized.

In this code, the registerTypeAdapter() method of GsonBuilder registers the custom serializer class, CustomProductSerializer.

The code to test the custom serializer is this.

The output on running the test is this.
Custom JSON Serialization with GSON

Creating a Custom Deserializer

Consider the following JSON that you need to deserialize into the Product object.

By default, Gson parses the JSON when it finds the fields in the object class with same name as it holds. So Gson by default would expect the fields of the Product class to be product-id, description, image-url, and price.

However, it is common to have different fields in the POJO class. In our example, the JSON has a key product-id while the productId field represents the same in the Product class. Same is with the image-url key whose corresponding field in Product is imageUrl.

As a result, the default serializer of Gson will not be able to deserialize the product-id and image-url keys to their corresponding fields in Product.

In order to parse this JSON into an object of Product class you can use a custom deserializer that implements the JsonDeserializer interface.

The code of the custom deserializer is this.

The JsonDeserializer interface takes a Type parameter which is the type of Java class to which the JSON will be converted to. Here it is the Product class.

The CustomProductSerializer class overrides the deserialize() method of JsonDeserializer which returns an instance of Product.

In the deserialize() method, the call to the getAsJsonObject() method converts the JsonElement passed as argument to deserialize() into JsonObject. The values within the JsonObject are themselves JsonElement which can be retrieved by their names. To convert these elements into their respective reference types, the getXXX() methods are called.

To use this deserializer, you need to register it through the GsonBuilder. The code to register and use the custom deserializer is this:

By registering the CustomProductDeserializer class you tell Gson to use the custom deserializer class whenever a JSON is deserialized to a Product type.

Line 5 registers the custom deserializer by calling the registerTypeAdapter() on the GsonBuilder.

Line 7 uses a Reader implementation of type InputStreamReader to read a JSON file, product.json that contains the JSON to be deserialized.

Line 8 calls the fromJson() method on the Gson instance to parse the JSON into a Product object.

The product.json file is this.

The code to test the custom deserializer is this.

The output on running the test is this.

Using GSON with Spring Boot

Out of the box, Spring Boot uses Jackson as the JSON parser library. If you wish to learn more about Jackson, check out this blog post.

But you can seamlessly pull in Gson in your Java application for JSON processing. To include Gson, you need to configure the GsonHttpMessageConverter. Whenever a request hits the controller, the @RestController annotation asks Spring to directly render the object as model to the response.

Spring looks for HttpMessageConverter to convert the Java object into JSON.

Spring by default configures the MappingJackson2HttpMessageConverter for this conversion. But to use Gson you need to configure Spring Boot to use GsonHttpMessageConverter instead.

The Maven POM

To use Gson in your Spring Boot application, declare Gson in your Spring Boot Maven POM.

To avoid conflicts with the use of Jackson and Gson, use the annotation @EnableAutoConfiguration(exclude = { JacksonAutoConfiguration.class }) in your application class and exclude the Jackson dependency from your POM.

To exclude Jackson dependency from the spring-boot-starter-web dependency add this in your POM.

Validate the GSON Converter

To verify that our Spring Boot application is indeed using the Gson converter, let’s create a controller class with a request handler method that handles the request to the default request mapping to the root /.

Let us run the application with debug enabled. Include the following property in your application.properties file to see the logging output.

When you access the application from the browser, the console output is this:

As you can see, the Spring Framework is using GSON’s GsonHttpMessageConverter to convert Product to JSON instead of the default Jackson library.

Summary

As you can see in this post, Spring Boot is very flexible in allowing JSON parsers, like GSON to be plugged in for parsing JSON.

Gson is a complete JSON parser with extensive support of Java Generics. Gson supports custom representations for objects and arbitrarily complex objects having deep inheritance hierarchies.

In terms of usage, I found Gson to be fairly simple. The API is intuitive and with minimal changes to source code, you can address complex serialization and deserialization requirements of JSON to and from Java objects.

Share

Leave a Reply