Gson tutorial

Gson tutorial shows how to work with JSON in Java using Gson library. We use three different Gson APIs to work with JSON.

JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write and for machines to parse and generate. It is less verbose and more readable than XML. The official Internet media type for JSON is application/json. The JSON filename extension is .json. JSON is directly consumable by JavaScript.

Gson library

Gson is a Java serialization/deserialization library to convert Java Objects into JSON and back. Gson was created by Google for internal use and later open sourced.

Gson Maven dependency

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

This is a Maven dependency for Gson.

Gson features

These are Gson features:

Gson API

Gson has three types of API:

Data binding API converts JSON to and from POJO using property accessors. Gson processes JSON data using data type adapters. It is similar to XML JAXB parser.

Tree model API creates an in-memory tree representation of the JSON document. It builds a tree of JsonElements. It is similar to XML DOM parser.

Streaming API is a low-level API that reads and writes JSON content as discrete tokens with JsonReader and JsonWriter. These classes read data as JsonTokens. This API has the lowest overhead and is fast in read/write operations. It is similar to Stax parser for XML.

Gson class

Gson is the main class for using Gson library. There are two basic ways to create Gson:

GsonBuilder can be used to build Gson with various configuration settings.

Gson toJson()

The toJson() method serializes the specified object into its equivalent JSON representation.

GsonToJson.java
package com.zetcode;

import com.google.gson.Gson;
import java.util.HashMap;
import java.util.Map;

public class GsonToJson {

    public static void main(String[] args) {

        Map<Integer, String> colours = new HashMap<>();
        colours.put(1, "blue");
        colours.put(2, "yellow");
        colours.put(3, "green");
        
        Gson gson = new Gson();
        
        String output = gson.toJson(colours);
        
        System.out.println(output);
    }
}

In the example, we serialize a map into JSON with toJSon() method.

{"1":"blue","2":"yellow","3":"green"}

This is the output of the example.

Gson fromJson()

The fromJson() method deserializes the specified JSON into an object of the specified class.

GsonFromJson.java
package com.zetcode;

import com.google.gson.Gson;

class Item {

    private String name;
    private int quantity;

    @Override
    public String toString() {
        return "Item{" + "name=" + name + ", quantity=" + quantity + '}';
    }
}

public class GsonFromJson {

    public static void main(String[] args) {

        String json_string = "{\"name\":\"chair\",\"quantity\":3}";

        Gson gson = new Gson();

        Item item = gson.fromJson(json_string, Item.class);

        System.out.println(item);
    }
}

The example uses fromJson() method to read JSON into a Java object.

class Item {

    private String name;
    private int quantity;

    @Override
    public String toString() {
        return "Item{" + "name=" + name + ", quantity=" + quantity + '}';
    }
}

Notice that getters and setters are not necessary.

Item{name=chair, quantity=3}

This is the output of the example.

GsonBuilder

GsonBuilder builds Gson with various configuration settings. GsonBuilder follows the builder pattern, and it is typically used by first invoking various configuration methods to set desired options, and finally calling create().

GsonBuilderEx.java
package com.zetcode;

import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.IOException;
import java.io.PrintWriter;

class Item {
    
    private String name;
    private int quantity;

    public Item(String name, int quantity) {
        this.name = name;
        this.quantity = quantity;
    }
}

public class GsonBuilderEx {

    public static void main(String[] args) throws IOException {

        try (PrintWriter writer = new PrintWriter(System.out)) {
            
            Gson gson = new GsonBuilder()
                    .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
                    .create();
            
            Item item1 = new Item("chair", 3);
            gson.toJson(item1, writer);
        }
    }
}

In the example, we write an object into JSON. We use GsonBuilder to create Gson.

Gson gson = new GsonBuilder()
        .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
        .create();

We create and configure Gson with GsonBuilder. The field naming policy is set to FieldNamingPolicy.UPPER_CAMEL_CASE.

{"Name":"chair","Quantity":3}

This is the output.

Gson pretty printing

Gson has two output modes: compact and pretty.

GsonPrettyPrinting.java
package com.zetcode;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.util.HashMap;
import java.util.Map;

public class GsonPrettyPrinting {

    public static void main(String[] args) {

        Gson gson = new GsonBuilder()
                .setPrettyPrinting()
                .create();
        
        Map<String, Integer> items = new HashMap<>();
        
        items.put("chair", 3);
        items.put("pencil", 1);
        items.put("book", 5);

        gson.toJson(items, System.out);
    }
}

The example pretty prints the JSON output.

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

The setPrettyPrinting() method sets the pretty printing mode.

{
  "chair": 3,
  "book": 5,
  "pencil": 1
}

This is the output of the example.

Gson write list

The following example writes a list of JSON objects into a file.

GsonWriteList.java
package com.zetcode;

import com.google.gson.Gson;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;

class Item {
    
    private String name;
    private int quantity;

    public Item(String name, int quantity) {
        this.name = name;
        this.quantity = quantity;
    }
}

public class GsonWriteList {

    public static void main(String[] args) throws IOException {

        try (Writer writer = new FileWriter("src/main/resources/items.json")) {
            
            Gson gson = new Gson();
            
            Item item1 = new Item("chair", 3);
            Item item2 = new Item("book", 5);
            Item item3 = new Item("pencil", 1);
            
            List<Item> items = new ArrayList<>();
            items.add(item1);
            items.add(item2);
            items.add(item3);
            
            gson.toJson(items, writer);
        }
    }
}

The example writes JSON data into items.json file.

Gson read into array

The next example reads data into a Java array.

$ cat items.json
[{"name":"chair","quantity":3},{"name":"book","quantity":5},{"name":"pencil","quantity":1}]

These are the contents of the items.json file.

GsonReadArray.java
package com.zetcode;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.Arrays;

class Item {
    
    private String name;
    private int quantity;

    @Override
    public String toString() {
        return "Item{" + "name=" + name + ", quantity=" + quantity + '}';
    }
}

public class GsonReadArray {
    
    public static void main(String[] args) throws IOException {
        
        Gson gson = new GsonBuilder().create();
        
        try (Reader reader = new FileReader("src/main/resources/items.json")) {
            
            Item[] items = gson.fromJson(reader, Item[].class);
            
            Arrays.stream(items).forEach( e -> {
                System.out.println(e);
            });
        }
    }
}

The example reads data from items.json file into an array. We print the contents of the array to the console.

Item[] items = gson.fromJson(reader, Item[].class);

The second parameter of fromJson() is an array class.

Gson read JSON from URL

The following example reads JSON data from a web page. We get JSON data from http://time.jsontest.com.

{
   "time": "02:44:19 PM",
   "milliseconds_since_epoch": 1496155459478,
   "date": "05-30-2017"
}

The GET request returns this JSON string.

GsonReadWebPage.java
package com.zetcode;

import com.google.gson.Gson;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;

class TimeData {

    private String time;
    private Long milliseconds_since_epoch;
    private String date;

    @Override
    public String toString() {
        return "TimeData{" + "time=" + time + ", milliseconds_since_epoch="
                + milliseconds_since_epoch + ", date=" + date + '}';
    }
}

public class GsonReadWebPage {

    public static void main(String[] args) throws IOException {

        String webPage = "http://time.jsontest.com";

        InputStream input = new URL(webPage).openStream();
        
        try (Reader reader = new InputStreamReader(input, "UTF-8")) {
        
            Gson gson = new Gson();
            TimeData td = gson.fromJson(reader, TimeData.class);
            
            System.out.println(td);
        }
    }
}

The code example reads JSON data from http://time.jsontest.com.

TimeData{time=02:46:04 PM, milliseconds_since_epoch=1496155564371, date=05-30-2017}

This is the output.

Gson excluding fields with @Expose

@Expose annotation indicates that a member should be exposed for JSON serialization or deserialization. The @Expose annotation can take two boolean parameters: serialize and deserialize. The @Expose annotation must be explicitly enabled with excludeFieldsWithoutExposeAnnotation() method.

GsonExcludeFields.java
package com.zetcode;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.annotations.Expose;

enum MaritalStatus {
    
    SINGLE,
    MARRIED,
    DIVORCED,
    UNKNOWN
}

class Person {
    
    @Expose
    private String firstName;
    
    @Expose
    private String lastName;

    private MaritalStatus maritalStatus;

    public Person(String firstName, String lastName, 
            MaritalStatus maritalStatus) {
        
        this.firstName = firstName;
        this.lastName = lastName;
        this.maritalStatus = maritalStatus;
    }
    
    public Person() {}
}

public class GsonExcludeFields {
    
    public static void main(String[] args) {
        
        Gson gson = new GsonBuilder()
                .excludeFieldsWithoutExposeAnnotation()
                .setPrettyPrinting()
                .create();
        
        Person p = new Person("Jack", "Sparrow", MaritalStatus.UNKNOWN);
        
        gson.toJson(p, System.out);        
    }
}

In the example, we exclude one field from serialization.

@Expose
private String firstName;

@Expose
private String lastName;

private MaritalStatus maritalStatus;

The marital status field will not be serialized, because it is not decorated with the @Expose annotation.

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

The field exclusion by @Expose annotation is enabled with excludeFieldsWithoutExposeAnnotation() method.

{
  "firstName": "Jack",
  "lastName": "Sparrow"
}

This is the output.

Gson data binding API

The data binding API converts JSON to and from POJO using property accessors. Gson processes JSON data using data type adapters.

Gson data binding API write

In the following example, we write data with the data binding API.

GsonDataBindApiWrite.java
package com.zetcode;

import com.google.gson.Gson;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

class Car {
    
    private String name;
    private String model;
    private int price;
    private String[] colours;

    public Car() {
    }

    public Car(String name, String model, int price, String[] colours) {
        this.name = name;
        this.model = model;
        this.price = price;
        this.colours = colours;
    }
}

public class GsonDataBindApiWrite {

    public static void main(String[] args) throws FileNotFoundException, IOException {

        List<Car> cars = new ArrayList<>();
        cars.add(new Car("Audi", "2012", 22000, new String[]{"gray", "red", "white"}));
        cars.add(new Car("Skoda", "2016", 14000, new String[]{"black", "gray", "white"}));
        cars.add(new Car("Volvo", "2010", 19500, new String[]{"black", "silver", "beige"}));

        try (FileWriter writer = new FileWriter(new File("src/main/resources/cars.json"))) {

            Gson gson = new Gson();
            gson.toJson(cars, writer);
        }
    }
}

In the example, we create a list of car objects and serialize it with Gson data binding API.

Gson gson = new Gson();
gson.toJson(cars, writer);

We pass the cars list to the toJson() method. Gson automatically maps car objects to JSON.

Gson data binding API read

In the following example, we read data with the data binding API.

GsonDataBindingApiRead.java
package com.zetcode;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

class Car {
    
    private String name;
    private String model;
    private int price;
    private String[] colours;

    public Car() {
    }

    public Car(String name, String model, int price, String[] colours) {
        this.name = name;
        this.model = model;
        this.price = price;
        this.colours = colours;
    }

    @Override
    public String toString() {
        return "Car{" + "name=" + name + ", model=" + model + 
                ", price=" + price + ", colours=" + Arrays.toString(colours) + '}';
    }
}

public class GsonDataBindingApiRead {
    
    public static void main(String[] args) throws FileNotFoundException, IOException {
        
        try (FileReader reader = new FileReader(new File("src/main/resources/cars.json"))) {

            Gson gson = new Gson();
            List<Car> cars = gson.fromJson(reader, 
                    new TypeToken<List<Car>>(){}.getType());
            
            cars.forEach(System.out::println);
        }        
    }
}

In the example, we read data from a JSON file into a list of car objects with Gson data binding API.

List<Car> cars = gson.fromJson(reader, 
        new TypeToken<List<Car>>(){}.getType());

Gson automatically maps JSON into Car objects. Because the type information is lost at runtime, we need to use the TypeToken to let Gson know what type we use.

Gson tree model API

Tree model API creates a tree representation of the JSON document in memory. It builds a tree of JsonElements. JsonElement is a class representing an element of Json. It could either be a JsonObject, a JsonArray, a JsonPrimitive, or a JsonNull.

Gson tree model write

In the following example, we use the Gson tree model API to write Java objects into JSON.

GsonTreeModelWrite.java
package com.zetcode;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

class Car {
    
    private String name;
    private String model;
    private int price;
    private String[] colours;

    public Car() {
    }

    public Car(String name, String model, int price, String[] colours) {
        this.name = name;
        this.model = model;
        this.price = price;
        this.colours = colours;
    }
}


public class GsonTreeModelWrite {
    
    public static void main(String[] args) throws FileNotFoundException, IOException {
        
        List<Car> cars = new ArrayList<>();
        cars.add(new Car("Audi", "2012", 22000, new String[]{"gray", "red", "white"}));
        cars.add(new Car("Skoda", "2016", 14000, new String[]{"black", "gray", "white"}));
        cars.add(new Car("Volvo", "2010", 19500, new String[]{"black", "silver", "beige"}));
        
        try (FileWriter writer = new FileWriter(new File("src/main/resources/cars.json"))) {

            Gson gson = new Gson();
            
            JsonElement tree = gson.toJsonTree(cars);
            JsonArray jarray = tree.getAsJsonArray();
            
            JsonElement jel = jarray.get(1);
            
            JsonObject object = jel.getAsJsonObject();
            object.addProperty("model", "2009");
            
            gson.toJson(tree, writer);
        }
    }        
}

A list of car objects is serialized into JSON format.

JsonElement tree = gson.toJsonTree(cars);

The toJsonTree method serializes the specified object into its equivalent representation as a tree of JsonElements.

JsonArray jarray = tree.getAsJsonArray();

We transform the tree into a JsonArray with getAsJsonArray() method.

JsonElement jel = jarray.get(1);

We get the second element from the array.

JsonObject object = jel.getAsJsonObject();
object.addProperty("model", "2009");

We modify a property.

gson.toJson(tree, writer);

Finally, we write the tree object into the file.

Gson tree model read

In the following example, we use the Gson tree model API to read Java objects from JSON.

cars.json
[{"name":"Audi","model":"2012","price":22000,"colours":["gray","red","white"]},
 {"name":"Skoda","model":"2009","price":14000,"colours":["black","gray","white"]},
 {"name":"Volvo","model":"2010","price":19500,"colours":["black","silver","beige"]}]

This is the JSON data in the cars.json file.

GsonTreeModelRead.java
package com.zetcode;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class GsonTreeModelRead {

    public static void main(String[] args) throws FileNotFoundException, IOException {

        try (FileReader reader = new FileReader(new File("src/main/resources/cars.json"))) {

            JsonParser parser = new JsonParser();
            JsonElement tree = parser.parse(reader);

            JsonArray array = tree.getAsJsonArray();

            for (JsonElement element : array) {

                if (element.isJsonObject()) {

                    JsonObject car = element.getAsJsonObject();

                    System.out.println("********************");
                    System.out.println(car.get("name").getAsString());
                    System.out.println(car.get("model").getAsString());
                    System.out.println(car.get("price").getAsInt());

                    JsonArray cols = car.getAsJsonArray("colors");

                    cols.forEach(col -> {
                        System.out.println(col);
                    });
                }
            }
        }
    }
}

In the example, we read JSON data from a file into a tree of JsonElements.

JsonParser parser = new JsonParser();
JsonElement tree = parser.parse(reader);

JsonParser parses JSON into a tree structure of JsonElements.

JsonArray array = tree.getAsJsonArray();

We get the tree as JsonArray.

for (JsonElement element : array) {

    if (element.isJsonObject()) {

        JsonObject car = element.getAsJsonObject();

        System.out.println("********************");
        System.out.println(car.get("name").getAsString());
        System.out.println(car.get("model").getAsString());
        System.out.println(car.get("price").getAsInt());

        JsonArray cols = car.getAsJsonArray("colors");

        cols.forEach(col -> {
            System.out.println(col);
        });
    }
}

We go through the JsonArray and print the contents of its elements.

Gson streaming API

Gson streaming API is a low-level API that reads and writes JSON as discrete tokens (JsonTokens). The main classes are JsonReader and JsonWriter. JsonToken is a structure, name or value type in a JSON-encoded string.

These are the JsonToken types:

Gson JsonWriter

JsonWriter writes a JSON encoded value to a stream, one token at a time. The stream includes both literal values (strings, numbers, booleans, and nulls) as well as the begin and end delimiters of objects and arrays. Each JSON document must contain one top-level array or object.

Objects are created with beginObject() and endObject() method calls. Within objects, tokens alternate between names and their values. Arrays are created within beginArray() and endArray() method calls.

GsonStreamApiWrite.java
package com.zetcode;

import com.google.gson.stream.JsonWriter;
import java.io.FileWriter;
import java.io.IOException;

public class GsonStreamApiWrite {
    
    public static void main(String[] args) throws IOException {
        
        try (JsonWriter writer = new JsonWriter(new FileWriter("src/main/resources/cars.json"))) {
        
            writer.beginObject(); 
            writer.name("name").value("Audi");
            writer.name("model").value("2012");
            writer.name("price").value(22000);
            
            writer.name("colours");
            writer.beginArray();
            writer.value("gray");
            writer.value("red");
            writer.value("white");
            writer.endArray();
            
            writer.endObject();
        } 
    }
}

In the example, we write one car object into JSON file.

try (JsonWriter writer = new JsonWriter(new FileWriter("src/main/resources/cars.json"))) {

A new JsonWriter is created. It writes to a cars.json file.

writer.beginObject(); 
...
writer.endObject();

As we stated above, each JSON document must have a top-level array or object. In our case, we have a top-level object.

writer.name("name").value("Audi");
writer.name("model").value("2012");
writer.name("price").value(22000);

We write key-value pairs to the document.

writer.name("colours");
writer.beginArray();
writer.value("gray");
writer.value("red");
writer.value("white");
writer.endArray();

Here we create an array.

Gson JsonReader

JsonReader reads a JSON encoded value as a stream of tokens.

GsonStreamApiRead.java
package com.zetcode;

import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import java.io.IOException;
import java.io.StringReader;

public class GsonStreamApiRead {

    public static void main(String[] args) throws IOException {

        String json_string = "{\"name\":\"chair\",\"quantity\":3}";

        JsonReader reader = new JsonReader(new StringReader(json_string));

        while (reader.hasNext()) {

            JsonToken nextToken = reader.peek();

            if (JsonToken.BEGIN_OBJECT.equals(nextToken)) {

                reader.beginObject();

            } else if (JsonToken.NAME.equals(nextToken)) {

                reader.nextName();

            } else if (JsonToken.STRING.equals(nextToken)) {

                String value = reader.nextString();
                System.out.format("%s: ", value);

            } else if (JsonToken.NUMBER.equals(nextToken)) {

                long value = reader.nextLong();
                System.out.println(value);
            }
        }
    }
}

The example reads data from a JSON string with JsonReader.

JsonReader reader = new JsonReader(new StringReader(json_string));

JsonReader object is created. It reads from a JSON string.

while (reader.hasNext()) {

In the while loop, we iterate over the tokens in the stream.

JsonToken nextToken = reader.peek();

We get the type of the next token with the peek() method.

reader.beginObject();

The beginObject() method consumes the next token from the JSON stream and asserts that it is the beginning of a new object.

reader.nextName();

The nextName() method returns the next JsonToken and consumes it.

String value = reader.nextString();
System.out.format("%s: ", value);

We get the next string value and print it to the console.

In this tutorial, we have shown how to work with JSON with Gson library. You might also be interested in the related tutorials: Jsoup tutorial, Java 8 forEach tutorial, Reading text files in Java, Reading and writing ICO images in Java, Java tutorial, Displaying image in Java.