Gson: Convert json to a java object

Google json provides methods to convert the json string to java objects. The Java object may be hierarchical. For this example we consider java objects of non generic type only. Gson uses the name to match the json property to the java field. There are two ways to convert json to java.

  • Using the com.google.gson.Gson class. Create a new instance of this class and use the method public T fromJson(String json, Class classOfT). classOfT is the java object to which the json is to be converted to.
  • The other way is to use the com.google.gson.GsonBuilder class. This class allows setting up certain features, such as - allowing null serialization or setting up custom serializing policies. Create a GsonBuilder, apply the features and then obtain the Gson class from the builder.

In this tutorial we look at the Gson class to de-serialize json from free music archive. The main class is the Albums class and it contains the list of Datasets. Each Dataset is one album. The way to approach the problem of deserialization is to build a java class such that the when Gson converts the Java class to JSON, the resultant JSON resembles the one we are trying to parse. Lets see this in action. If you look at the JSON, it starts with a root object that has properties such as title, message, errors, etc.

{
title: "Free Music Archive - Albums",
message: "",
errors: [ ],
total: "11259",
total_pages: 2252,
page: 1,
limit: "5",
dataset: [
{
......

Lets ignore the dataset for now. Lets just build a java class to hold the root. We call that class Albums. We will make the fields public for brevity, but you might want to make them private and use setters.

class Albums {
	public String title;
	public String message;
	public String[] errors = new String[]{};
	public String total;
	public int total_pages;
	public int page;
	public String limit;
}

Lets convert this to JSON and see how it looks

import com.google.gson.Gson;

public class JavaToJsonAndBack {

	public static void main(String[] args) {
		Albums albums = new Albums();
		albums.title = "Free Music Archive - Albums";
		albums.message = "";
		albums.total = "11259";
		albums.total_pages = 2252;
		albums.page = 1;
		albums.limit = "5";
		GsonBuilder builder = new GsonBuilder();
		Gson gson = builder.create();
		System.out.println(gson.toJson(albums));

	}
}

This is how the resulting JSON looks like

{"title":"Free Music Archive - Albums","message":"","errors":[],
"total":"11259","total_pages":2252,"page":1,"limit":"5"}

This is a good beginning. Notice how we initialized errors to an empty array. Otherwise Gson would think its null and either ignore it or print null if we allow null serialization. In this case, it looks like we are better off with using a List for errors. Lets change the errors variable to

public List<String> errors = new ArrayList<String>();

We have used a GsonBuilder since that allows us to customize the conversion. we will see its benefit later in the example. The next step is to build a class for the dataset. Lets see how the dataset JSON looks

dataset: [
{
album_id: "7596",
album_title: "!!! - Live @ KEXP 7/24/2010",
......
album_images: [
{
image_id: "10574",
user_id: null,
.....
}
],
tags: [ ]

For this tutorial we will be considering only some fields from ‘dataset’ and ‘album_images’. The other fields can be added similarly. The dataset contains an array of album and each album contains, besides other fields, an array of album_images. We build a java class for each JSON object. We have already built a java class for albums. Now lets built classes for dataset and album_image.

class Dataset {
	public String album_id;
	public String album_title;
}

class AlbumImages {
	public String image_id;
	public String user_id;
}
Lets create a Dataset.
Dataset dataset = new Dataset();
dataset.album_id = "7596";
dataset.album_title = "Album 1";
System.out.println(gson.toJson(dataset));
the json
{"album_id":"7596","album_title":"Album 1"}
The album image
AlbumImages image = new AlbumImages();
image.image_id = "1";
System.out.println(gson.toJson(image));

The album image json

{"image_id":"1"}

See how gson has not printed user_id since its null. We need to be able to tell json to serialize null fields too. GsonBuilder helps us do that

builder.serializeNulls();

The album image json now looks like this

{"image_id":"1","user_id":null}

Lets now wire up the dataset into the albums class and the AlbumImage into the dataset class. To the Albums class we add the List of Dataset

List<Dataset> dataset  = new ArrayList<Dataset>();
To the Dataset class we add a List of images
List<AlbumImages> images = new ArrayList<AlbumImages>();
Lets change the main method to add dataset to the album and image to the dataset
dataset.images.add(image);
albums.dataset.add(dataset);

Here’s how our JSON looks now

{"title":"Free Music Archive - Albums","message":"","errors":[],"total":"11259",
"total_pages":2252,"page":1,"limit":"5",
"dataset":[{"album_id":"7596","album_title":"Album 1",
"images":[{"image_id":"1","user_id":null}]}]}

Lets turn on pretty printing so that our JSON looks better. However, we do that only during developement. If you are actually designing a server that provides JSON data, then make the JSON as compact as possible.

builder.setPrettyPrinting().serializeNulls();

Here’s our formatted JSON now

{
  "title": "Free Music Archive - Albums",
  "message": "",
  "errors": [],
  "total": "11259",
  "total_pages": 2252,
  "page": 1,
  "limit": "5",
  "dataset": [
    {
      "album_id": "7596",
      "album_title": "Album 1",
      "images": [
        {
          "image_id": "1",
          "user_id": null
        }
      ]
    }
  ]
}

This looks good, however we want to change the name of the ‘images’ element in dataset to ‘album_images’. Lets assume we cant change the java name because it follows the java naming policy. We can use annotation on the field to specify the json name to use for a particular java property. Here’s how to do that

@SerializedName("album_images")
List<AlbumImages> images = new ArrayList<AlbumImages>();
our JSON now contains the name 'album_images'
"dataset": [
    {
      "album_id": "7596",
      "album_title": "Album 1",
      "album_images": [
        {
          "image_id": "1",
     .........

If you dont want to bind your java class to GSON then there is another way to do this. Lets add one more field to the AlbumImage class. We call it albumId. However, we want to name the field album_id in the JSON. To do that we need to specify a NamingStrategy in the GsonBuilder.

builder.setFieldNamingStrategy(new FieldNamingStrategy() {

			@Override
			public String translateName(Field f) {
				if (f.getName().equals("albumId"))
					return "album_id";
				else
					return f.getName();
			}
		});

The translateName method is called for all fields and if the name matches albumId we convert the name to album_id and send it back otherwise we send the default. the album_images element now looks like this

 "album_images": [
        {
          "image_id": "1",
          "user_id": null,
          "album_id": "10"
        }

GsonBuilder provides a lot of other customization. You can disable HTML escaping, exclude fields with specific modifiers (e.g. exclude all protected fields), set custom type adapters, set exclusion policies etc. Look at the GsonBuilder JavaDoc for the complete list. You can now use the Albums class and parse the JSON using the fromJson method (you will have to add the other properties)

// url is the free music archive url.
Albums albums = gson.fromJson(IOUtils.toString(new URL(url)), Albums.class);

Before we close the tutorial lets look at the complete class. we would appreciate if you could ‘Like us’ on Facebook and ‘Follow us’ on Google. The Albums class

class Albums {
	public String title;
	public String message;
	public List errors = new ArrayList();
	public String total;
	public int total_pages;
	public int page;
	public String limit;
	List dataset = new ArrayList();
}

The Dataset class

class Dataset {
	public String album_id;
	public String album_title;
	@SerializedName("album_images")
	List<<AlbumImages> images = new ArrayList<AlbumImages>();
}

The AlbumImage class

class AlbumImages {
	public String image_id;
	public String user_id;
	public String albumId;
}

The main method

public static void main(String[] args) {
		Albums albums = new Albums();
		albums.title = "Free Music Archive - Albums";
		albums.message = "";
		albums.total = "11259";
		albums.total_pages = 2252;
		albums.page = 1;
		albums.limit = "5";
		GsonBuilder builder = new GsonBuilder();
		builder.setPrettyPrinting().serializeNulls();
		builder.setFieldNamingStrategy(new FieldNamingStrategy() {

			@Override
			public String translateName(Field f) {
				if (f.getName().equals("albumId"))
					return "album_id";
				else
					return f.getName();
			}
		});
		Gson gson = builder.create();

		Dataset dataset = new Dataset();
		dataset.album_id = "7596";
		dataset.album_title = "Album 1";

		AlbumImages image = new AlbumImages();
		image.image_id = "1";
		image.albumId = "10";
		dataset.images.add(image);
		albums.dataset.add(dataset);

		System.out.println(gson.toJson(albums));

	}

(Note: This article’s original links is here )

 Gson: Introduction Gson: parsing json to java token by token 

Comments