Google Gson is a simple Java-based library to serialize Java objects to JSON and vice versa. It is an open-source library developed by Google.
The following points highlight why you should be using this library −
Standardized − Gson is a standardized library that is managed by Google.
Efficient − It is a reliable, fast, and efficient extension to the Java standard library.
Optimized − The library is highly optimized.
Support Generics − It provides extensive support for generics.
Supports complex inner classes − It supports complex objects with deep inheritance hierarchies.
Here is a list of some of the most prominent features of Gson −
Easy to use − Gson API provides a high-level facade to simplify commonly used use-cases.
No need to create mapping − Gson API provides default mapping for most of the objects to be serialized.
Performance − Gson is quite fast and is of low memory footprint. It is suitable for large object graphs or systems.
Clean JSON − Gson creates a clean and compact JSON result which is easy to read.
No Dependency − Gson library does not require any other library apart from JDK.
Open Source − Gson library is open source; it is freely available.
Gson provides three alternative ways to process JSON −
It reads and writes JSON content as discrete events. JsonReader and JsonWriter read/write the data as token, referred as JsonToken.
It is the most powerful approach among the three approaches to process JSON. It has the lowest overhead and it is quite fast in read/write operations. It is analogous to Stax parser for XML.
It prepares an in-memory tree representation of the JSON document. It builds a tree of JsonObject nodes. It is a flexible approach and is analogous to DOM parser for XML.
It converts JSON to and from POJO (Plain Old Java Object) using property accessor. Gson reads/writes JSON using data type adapters. It is analogous to JAXB parser for XML.
If you still want to set up a local environment for Java programming language, then this section will guide you on how to download and set up Java on your machine. Please follow the steps given below, to set up the environment.
Java SE is freely available from the link Download Java. So you download a version based on your operating system.
Follow the instructions to download Java and run the .exe to install Java on your machine. Once you have installed Java on your machine, you would need to set the environment variables to point to their correct installation directories.
Assuming you have installed Java in c:\Program Files\java\jdk directory −
Right-click on 'My Computer' and select 'Properties'.
Click on the 'Environment variables' button under the 'Advanced' tab.
Next, alter the 'Path' variable so that it also contains the path to the Java executable. For example, if the path is currently set to 'C:\WINDOWS\SYSTEM32', then change your path to read 'C:\WINDOWS\SYSTEM32;c:\Program Files\java\jdk\bin'.
Assuming you have installed Java in c:\Program Files\java\jdk directory −
Edit the 'C:\autoexec.bat' file and add the following line at the end: 'SET PATH=%PATH%;C:\Program Files\java\jdk\bin'
The environment variable PATH should be set to point to where the Java binaries have been installed. Refer to your shell documentation if you have trouble doing this.
For example, if you use bash as your shell, then you would add the following line to the end of your '.bashrc: export PATH=/path/to/java:$PATH'
To write your Java programs, you will need a text editor. There are quite a few sophisticated IDEs available in the market. But for now, you can consider one of the following −
Notepad − On Windows, you can use any simple text editor like Notepad (Recommended for this tutorial) or TextPad.
Netbeans − It is a Java IDE that is open-source and free which can be downloaded from https://netbeans.org/index.html.
Eclipse − It is also a Java IDE developed by the Eclipse open-source community and can be downloaded from https://www.eclipse.org/.
Download the latest version of Gson jar file from gson-2.3.1.jar. At the time of writing this tutorial, we downloaded gson-2.3.1.jar and copied it into C:\>gson folder.
OS | Archive name |
---|---|
Windows | gson-2.3.1.jar |
Linux | gson-2.3.1.jar |
Mac | gson-2.3.1.jar |
Set the GSON_HOME environment variable to point to the base directory location where Gson jar is stored on your machine.
OS | Output |
---|---|
Windows | Set the environment variable GSON_HOME to C:\gson |
Linux | export GSON_HOME=/usr/local/gson |
Mac | export GSON_HOME=/Library/gson |
Set the CLASSPATH environment variable to point to the Gson jar location.
OS | Output |
---|---|
Windows | Set the environment variable CLASSPATH to %CLASSPATH%;%GSON_HOME%\gson-2.3.1.jar;.; |
Linux | export CLASSPATH=$CLASSPATH:$GSON_HOME/gson-2.3.1.jar:. |
Mac | export CLASSPATH=$CLASSPATH:$GSON_HOME/gson-2.3.1.jar:. |
Before going into the details of the Google Gson library, let's see an application in action. In this example, we've created a Student class. We'll create a JSON string with student details and deserialize it to student object and then serialize it to an JSON String.
Create a Java class file named GsonTester in C:\>GSON_WORKSPACE.
File − GsonTester.java
import com.google.gson.Gson; import com.google.gson.GsonBuilder; public class GsonTester { public static void main(String[] args) { String jsonString = "{\"name\":\"Mahesh\", \"age\":21}"; GsonBuilder builder = new GsonBuilder(); builder.setPrettyPrinting(); Gson gson = builder.create(); Student student = gson.fromJson(jsonString, Student.class); System.out.println(student); jsonString = gson.toJson(student); System.out.println(jsonString); } } class Student { private String name; private int age; public Student(){} public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String toString() { return "Student [ name: "+name+", age: "+ age+ " ]"; } }
Compile the classes using javac compiler as follows −
C:\GSON_WORKSPACE>javac GsonTester.java
Now run the GsonTester to see the result −
C:\GSON_WORKSPACE>java GsonTester
Verify the output.
Student [ name: Mahesh, age: 21 ] { "name" : "Mahesh", "age" : 21 }
Following are the important steps to be considered here.
Create a Gson object. It is a reusable object.
GsonBuilder builder = new GsonBuilder(); builder.setPrettyPrinting(); Gson gson = builder.create();
Use fromJson() method to get the Object from the JSON. Pass Json string / source of Json string and object type as parameter.
//Object to JSON Conversion Student student = gson.fromJson(jsonString, Student.class);
Use toJson() method to get the JSON string representation of an object.
//Object to JSON Conversion jsonString = gson.toJson(student);
Gson is the main actor class of Google Gson library. It provides functionalities to convert Java objects to matching JSON constructs and vice versa. Gson is first constructed using GsonBuilder and then, toJson(Object) or fromJson(String, Class) methods are used to read/write JSON constructs.
Following is the declaration for com.google.gson.Gson class −
public final class Gson extends Object
Sr.No | Constructor & Description |
---|---|
1 |
Gson() Constructs a Gson object with default configuration. |
Sr.No | Method & Description |
---|---|
1 |
<T> T fromJson(JsonElement json, Class<T> classOfT) This method deserializes the Json read from the specified parse tree into an object of the specified type. |
2 |
<T> T fromJson(JsonElement json, Type typeOfT) This method deserializes the Json read from the specified parse tree into an object of the specified type. |
3 |
<T> T fromJson(JsonReader reader, Type typeOfT) Reads the next JSON value from reader and convert it to an object of type typeOfT. |
4 |
<T> T fromJson(Reader json, Class<T> classOfT) This method deserializes the Json read from the specified reader into an object of the specified class. |
5 |
<T> T fromJson(Reader json, Type typeOfT) This method deserializes the Json read from the specified reader into an object of the specified type. |
6 |
<T> T fromJson(String json, Class<T> classOfT) This method deserializes the specified Json into an object of the specified class. |
7 |
<T> T fromJson(String json, Type typeOfT) This method deserializes the specified Json into an object of the specified type. |
8 |
<T> TypeAdapter<T> getAdapter(Class<T> type) Returns the type adapter for type. |
9 |
<T> TypeAdapter<T> getAdapter(TypeToken<T> type) Returns the type adapter for type. |
10 |
<T> TypeAdapter<T> getDelegateAdapter(TypeAdapterFactory skipPast, TypeToken<T> type) This method is used to get an alternate type adapter for the specified type. |
11 |
String toJson(JsonElement jsonElement) Converts a tree of JsonElements into its equivalent JSON representation. |
12 |
void toJson(JsonElement jsonElement, Appendable writer) Writes out the equivalent JSON for a tree of JsonElements. |
13 |
void toJson(JsonElement jsonElement, JsonWriter writer) Writes the JSON for jsonElement to writer. |
14 |
String toJson(Object src) This method serializes the specified object into its equivalent Json representation. |
15 |
void toJson(Object src, Appendable writer) This method serializes the specified object into its equivalent Json representation. |
16 |
String toJson(Object src, Type typeOfSrc) This method serializes the specified object, including those of generic types, into its equivalent Json representation. |
17 |
void toJson(Object src, Type typeOfSrc, Appendable writer) This method serializes the specified object, including those of generic types, into its equivalent Json representation. |
18 |
void toJson(Object src, Type typeOfSrc, JsonWriter writer) Writes the JSON representation of src of type typeOfSrc to writer. |
19 |
JsonElement toJsonTree(Object src) This method serializes the specified object into its equivalent representation as a tree of JsonElements. |
20 |
JsonElement toJsonTree(Object src, Type typeOfSrc) This method serializes the specified object, including those of generic types, into its equivalent representation as a tree of JsonElements. |
21 |
String toString() |
This class inherits methods from the following class −
Create the following Java program using any editor of your choice, and save it at, say, C:/> GSON_WORKSPACE
File − GsonTester.java
import com.google.gson.Gson; import com.google.gson.GsonBuilder; public class GsonTester { public static void main(String[] args) { String jsonString = "{\"name\":\"Mahesh\", \"age\":21}"; GsonBuilder builder = new GsonBuilder(); builder.setPrettyPrinting(); Gson gson = builder.create(); Student student = gson.fromJson(jsonString, Student.class); System.out.println(student); jsonString = gson.toJson(student); System.out.println(jsonString); } } class Student { private String name; private int age; public Student(){} public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String toString() { return "Student [ name: "+name+", age: "+ age+ " ]"; } }
Compile the classes using javac compiler as follows −
C:\GSON_WORKSPACE>javac GsonTester.java
Now run the GsonTester to see the result −
C:\GSON_WORKSPACE>java GsonTester
Verify the output
Student [ name: Mahesh, age: 21 ] { "name" : "Mahesh", "age" : 21 }
Let's serialize a Java object to a Json file and then read that Json file to get the object back. In this example, we've created a Student class. We'll create a student.json file which will have a json representation of Student object.
Create a Java class file named GsonTester in C:\>GSON_WORKSPACE.
import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import com.google.gson.Gson; import com.google.gson.GsonBuilder; public class GsonTester { public static void main(String args[]) { GsonTester tester = new GsonTester(); try { Student student = new Student(); student.setAge(10); student.setName("Mahesh"); tester.writeJSON(student); Student student1 = tester.readJSON(); System.out.println(student1); } catch(FileNotFoundException e) { e.printStackTrace(); } catch(IOException e) { e.printStackTrace(); } } private void writeJSON(Student student) throws IOException { GsonBuilder builder = new GsonBuilder(); Gson gson = builder.create(); FileWriter writer = new FileWriter("student.json"); writer.write(gson.toJson(student)); writer.close(); } private Student readJSON() throws FileNotFoundException { GsonBuilder builder = new GsonBuilder(); Gson gson = builder.create(); BufferedReader bufferedReader = new BufferedReader( new FileReader("student.json")); Student student = gson.fromJson(bufferedReader, Student.class); return student; } } class Student { private String name; private int age; public Student(){} public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String toString() { return "Student [ name: "+name+", age: "+ age+ " ]"; } }
Compile the classes using javac compiler as follows −
C:\GSON_WORKSPACE>javac GsonTester.java
Now run the GsonTester to see the result −
C:\GSON_WORKSPACE>java GsonTester
Verify the Output
Student [ name: Mahesh, age: 10 ]
Data Binding API is used to convert JSON to and from POJO (Plain Old Java Object) using property accessor or using annotations. It is of two types.
Primitives Data Binding − Converts JSON to and from Java Maps, Lists, Strings, Numbers, Booleans, and NULL objects.
Objects Data Binding − Converts JSON to and from any JAVA type.
Gson reads/writes JSON for both types of data bindings. Data Binding is analogous to JAXB parser for XML.
Primitives data binding refers to mapping of JSON to JAVA Core data types and inbuilt collections. Gson provides various inbuilt adapters which can be used to serialize/deserialize primitive data types.
Let's see primitive data binding in action. Here we'll map JAVA basic types directly to JSON and vice versa.
Create a Java class file named GsonTester in C:\>Gson_WORKSPACE.
File − GsonTester.java
import java.util.Arrays; import com.google.gson.Gson; public class GsonTester { public static void main(String args[]) { Gson gson = new Gson(); String name = "Mahesh Kumar"; long rollNo = 1; boolean verified = false; int[] marks = {100,90,85}; //Serialization System.out.println("{"); System.out.println("name: " + gson.toJson(name) +","); System.out.println("rollNo: " + gson.toJson(rollNo) +","); System.out.println("verified: " + gson.toJson(verified) +","); System.out.println("marks:" + gson.toJson(marks)); System.out.println("}"); //De-serialization name = gson.fromJson("\"Mahesh Kumar\"", String.class); rollNo = gson.fromJson("1", Long.class); verified = gson.fromJson("false", Boolean.class); marks = gson.fromJson("[100,90,85]", int[].class); System.out.println("name: " + name); System.out.println("rollNo: " + rollNo); System.out.println("verified: " +verified); System.out.println("marks:" + Arrays.toString(marks)); } }
Compile the classes using javac compiler as follows −
C:\GSON_WORKSPACE>javac GsonTester.java
Now run the GsonTester to see the result −
C:\GSON_WORKSPACE>java GsonTester
Verify the output.
{ name: "Mahesh Kumar", rollNo: 1, verified: false, marks:[100,90,85] } name: Mahesh Kumar rollNo: 1 verified: false marks:[100, 90, 85]
Object data binding refers to mapping of JSON to any JAVA Object.
//Create a Gson instance Gson gson = new Gson(); //map Student object to JSON content String jsonString = gson.toJson(student); //map JSON content to Student object Student student1 = gson.fromJson(jsonString, Student.class);
Let's see object data binding in action. Here we'll map JAVA Object directly to JSON and vice versa.
Create a Java class file named GsonTester in C:\>GSON_WORKSPACE.
import com.google.gson.Gson; public class GsonTester { public static void main(String args[]) { Gson gson = new Gson(); Student student = new Student(); student.setAge(10); student.setName("Mahesh"); String jsonString = gson.toJson(student); System.out.println(jsonString); Student student1 = gson.fromJson(jsonString, Student.class); System.out.println(student1); } } class Student { private String name; private int age; public Student(){} public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String toString() { return "Student [ name: "+name+", age: "+ age+ " ]"; } }
Compile the classes using javac compiler as follows −
C:\GSON_WORKSPACE>javac GsonTester.java
Now run the GsonTester to see the result −
C:\GSON_WORKSPACE>java GsonTester
Verify the output.
{"name":"Mahesh","age":10} Student [ name: Mahesh, age: 10 ]
Tree Model prepares an in-memory tree representation of the JSON document. It builds a tree of JsonObject nodes. It is a flexible approach and is analogous to DOM parser for XML.
JsonParser provides a pointer to the root node of the tree after reading the JSON. Root Node can be used to traverse the complete tree. Consider the following code snippet to get the root node of a provided JSON String.
//Create an JsonParser instance JsonParser parser = new JsonParser(); String jsonString = "{\"name\":\"Mahesh Kumar\", \"age\":21,\"verified\":false,\"marks\": [100,90,85]}"; //create tree from JSON JsonElement rootNode = parser.parse(jsonString);
Get each node using relative path to the root node while traversing the tree and process the data. The following code snippet shows how you can traverse a tree.
JsonObject details = rootNode.getAsJsonObject(); JsonElement nameNode = details.get("name"); System.out.println("Name: " +nameNode.getAsString()); JsonElement ageNode = details.get("age"); System.out.println("Age: " + ageNode.getAsInt());
Create a Java class file named GsonTester in C:\>GSON_WORKSPACE.
File − GsonTester.java
import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.JsonPrimitive; public class GsonTester { public static void main(String args[]) { String jsonString = "{\"name\":\"Mahesh Kumar\", \"age\":21,\"verified\":false,\"marks\": [100,90,85]}"; JsonParser parser = new JsonParser(); JsonElement rootNode = parser.parse(jsonString); if (rootNode.isJsonObject()) { JsonObject details = rootNode.getAsJsonObject(); JsonElement nameNode = details.get("name"); System.out.println("Name: " +nameNode.getAsString()); JsonElement ageNode = details.get("age"); System.out.println("Age: " + ageNode.getAsInt()); JsonElement verifiedNode = details.get("verified"); System.out.println("Verified: " + (verifiedNode.getAsBoolean() ? "Yes":"No")); JsonArray marks = details.getAsJsonArray("marks"); for (int i = 0; i < marks.size(); i++) { JsonPrimitive value = marks.get(i).getAsJsonPrimitive(); System.out.print(value.getAsInt() + " "); } } } }
Compile the classes using javac compiler as follows −
C:\GSON_WORKSPACE>javac GsonTester.java
Now run the GsonTester to see the result −
C:\GSON_WORKSPACE>java GsonTester
Verify the output.
Name: Mahesh Kumar Age: 21 Verified: No 100 90 85
Streaming API is used to read JSON token by token. It reads and writes JSON content as discrete events. JsonReader and JsonWriter read/write the data as token, referred as JsonToken.
It is the most powerful approach among the three approaches to process JSON. It has the lowest overhead and it is quite fast in read/write operations. It is analogous to Stax parser for XML.
In this chapter, we will showcase the usage of GSON streaming APIs to read JSON data. Streaming API works with the concept of token and every details of Json is to be handled carefully.
//create JsonReader object and pass it the json source or json text. JsonReader reader = new JsonReader(new StringReader(jsonString)); //start reading json reader.beginObject(); //get the next token JsonToken token = reader.peek(); //check the type of the token if (token.equals(JsonToken.NAME)) { //get the current token fieldname = reader.nextName(); }
Let's see JsonReader in action. Create a Java class file named GsonTester in C:\>GSON_WORKSPACE.
import java.io.IOException; import java.io.StringReader; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; public class GsonTester { public static void main(String args[]) { String jsonString = "{\"name\":\"Mahesh Kumar\", \"age\":21,\"verified\":false,\"marks\": [100,90,85]}"; JsonReader reader = new JsonReader(new StringReader(jsonString)); try { handleJsonObject(reader); } catch (IOException e) { e.printStackTrace(); } } private static void handleJsonObject(JsonReader reader) throws IOException { reader.beginObject(); String fieldname = null; while (reader.hasNext()) { JsonToken token = reader.peek(); if (token.equals(JsonToken.BEGIN_ARRAY)) { System.out.print("Marks [ "); handleJsonArray(reader); System.out.print("]"); } else if (token.equals(JsonToken.END_OBJECT)) { reader.endObject(); return; } else { if (token.equals(JsonToken.NAME)) { //get the current token fieldname = reader.nextName(); } if ("name".equals(fieldname)) { //move to next token token = reader.peek(); System.out.println("Name: "+reader.nextString()); } if("age".equals(fieldname)) { //move to next token token = reader.peek(); System.out.println("Age:" + reader.nextInt()); } if("verified".equals(fieldname)) { //move to next token token = reader.peek(); System.out.println("Verified:" + reader.nextBoolean()); } } } } private static void handleJsonArray(JsonReader reader) throws IOException { reader.beginArray(); String fieldname = null; while (true) { JsonToken token = reader.peek(); if (token.equals(JsonToken.END_ARRAY)) { reader.endArray(); break; } else if (token.equals(JsonToken.BEGIN_OBJECT)) { handleJsonObject(reader); } else if (token.equals(JsonToken.END_OBJECT)) { reader.endObject(); } else { System.out.print(reader.nextInt() + " "); } } } }
Compile the classes using javac compiler as follows −
C:\GSON_WORKSPACE>javac GsonTester.java
Now run the GsonTester to see the result −
C:\GSON_WORKSPACE>java GsonTester
Verify the output.
Name: Mahesh Kumar Age:21 Verified:false Marks [ 100 90 85 ]
In this chapter, we will discuss the serialization/deserialization of arrays, collections, and generics.
int[] marks = {100,90,85}; //Serialization System.out.println("marks:" + gson.toJson(marks)); //De-serialization marks = gson.fromJson("[100,90,85]", int[].class); System.out.println("marks:" + Arrays.toString(marks));
Let's see Array serialization/de-serialization in action. Create a Java class file named GsonTester in C:\>GSON_WORKSPACE.
File − GsonTester.java
import java.util.Arrays; import com.google.gson.Gson; public class GsonTester { public static void main(String args[]) { Gson gson = new Gson(); int[] marks = {100,90,85}; String[] names = {"Ram","Shyam","Mohan"}; //Serialization System.out.print("{"); System.out.print("marks:" + gson.toJson(marks) + ","); System.out.print("names:" + gson.toJson(names)); System.out.println("}"); //De-serialization marks = gson.fromJson("[100,90,85]", int[].class); names = gson.fromJson("[\"Ram\",\"Shyam\",\"Mohan\"]", String[].class); System.out.println("marks:" + Arrays.toString(marks)); System.out.println("names:" + Arrays.toString(names)); } }
Compile the classes using javac compiler as follows −
C:\GSON_WORKSPACE>javac GsonTester.java
Now run the GsonTester to see the result −
C:\GSON_WORKSPACE>java GsonTester
Verify the output.
{marks:[100,90,85],names:["Ram","Shyam","Mohan"]} marks:[100, 90, 85] names:[Ram, Shyam, Mohan]
List marks = new ArrayList(); //Serialization System.out.println("marks:" + gson.toJson(marks)); //De-serialization //get the type of the collection. Type listType = new TypeToken<list>(){}.getType(); //pass the type of collection marks = gson.fromJson("[100,90,85]", listType); System.out.println("marks:" +marks);</list>
Let's see Collection serialization/de-serialization in action. Create a Java class file named GsonTester in C:\>GSON_WORKSPACE.
File − GsonTester.java
import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collection; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; public class GsonTester { public static void main(String args[]) { Gson gson = new Gson(); Collection<Integer> marks = new ArrayList<Integer>(); marks.add(100); marks.add(90); marks.add(85); //Serialization System.out.print("{"); System.out.print("marks:" + gson.toJson(marks)); System.out.println("}"); //De-serialization Type listType = new TypeToken<Collection<Integer>>(){}.getType(); marks = gson.fromJson("[100,90,85]", listType); System.out.println("marks:" +marks); } }
Compile the classes using javac compiler as follows −
C:\GSON_WORKSPACE>javac GsonTester.java
Now run the GsonTester to see the result −
C:\GSON_WORKSPACE>java GsonTester
Verify the output.
{marks:[100,90,85]} marks:[100, 90, 85]
Gson uses Java reflection API to get the type of the object to which a Json text is to be mapped. But with generics, this information is lost during serialization. To counter this problem, Gson provides a class com.google.gson.reflect.TypeToken to store the type of the generic object.
Let's see Generics serialization/de-serialization in action. Create a Java class file named GsonTester in C:\>GSON_WORKSPACE.
File − GsonTester.java
import java.lang.reflect.Type; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; public class GsonTester { public static void main(String args[]) { // create a shape class of type circle. Shape<Circle> shape = new Shape<Circle>(); // Create a Circle object Circle circle = new Circle(5.0); //assign circle to shape shape.setShape(circle); Gson gson = new Gson(); // Define a Type shapeType of type circle. Type shapeType = new TypeToken<Shape<Circle>>() {}.getType(); //Serialize the json as ShapeType String jsonString = gson.toJson(shape, shapeType); System.out.println(jsonString); Shape shape1 = gson.fromJson(jsonString, Shape.class); System.out.println(shape1.get().getClass()); System.out.println(shape1.get().toString()); System.out.println(shape1.getArea()); Shape shape2 = gson.fromJson(jsonString, shapeType); System.out.println(shape2.get().getClass()); System.out.println(shape2.get().toString()); System.out.println(shape2.getArea()); } } class Shape <T> { public T shape; public void setShape(T shape) { this.shape = shape; } public T get() { return shape; } public double getArea() { if(shape instanceof Circle) { return ((Circle) shape).getArea(); } else { return 0.0; } } } class Circle { private double radius; public Circle(double radius){ this.radius = radius; } public String toString() { return "Circle"; } public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } public double getArea() { return (radius*radius*3.14); } }
Compile the classes using javac compiler as follows −
C:\GSON_WORKSPACE>javac GsonTester.java
Now run the GsonTester to see the result −
C:\GSON_WORKSPACE>java GsonTester
Verify the output.
{"shape":{"radius":5.0}} class com.google.gson.internal.LinkedTreeMap {radius = 5.0} 0.0 class Circle Circle 78.5
In this chapter, we will explain serialization/deserialization of classes having inner classes.
Student student = new Student(); student.setRollNo(1); Student.Name name = student.new Name(); name.firstName = "Mahesh"; name.lastName = "Kumar"; student.setName(name); //serialize inner class object String nameString = gson.toJson(name); System.out.println(nameString); //deserialize inner class object name = gson.fromJson(nameString,Student.Name.class); System.out.println(name.getClass());
Let's see an example of serialization/de-serialization of class with an inner class in action. Create a Java class file named GsonTester in C:\>GSON_WORKSPACE.
File − GsonTester.java
import com.google.gson.Gson; public class GsonTester { public static void main(String args[]) { Student student = new Student(); student.setRollNo(1); Student.Name name = student.new Name(); name.firstName = "Mahesh"; name.lastName = "Kumar"; student.setName(name); Gson gson = new Gson(); String jsonString = gson.toJson(student); System.out.println(jsonString); student = gson.fromJson(jsonString, Student.class); System.out.println("Roll No: "+ student.getRollNo()); System.out.println("First Name: "+ student.getName().firstName); System.out.println("Last Name: "+ student.getName().lastName); String nameString = gson.toJson(name); System.out.println(nameString); name = gson.fromJson(nameString,Student.Name.class); System.out.println(name.getClass()); System.out.println("First Name: "+ name.firstName); System.out.println("Last Name: "+ name.lastName); } } class Student { private int rollNo; private Name name; public int getRollNo() { return rollNo; } public void setRollNo(int rollNo) { this.rollNo = rollNo; } public Name getName() { return name; } public void setName(Name name) { this.name = name; } class Name { public String firstName; public String lastName; } }
Compile the classes using javac compiler as follows −
C:\GSON_WORKSPACE>javac GsonTester.java
Now run the GsonTester to see the result −
C:\GSON_WORKSPACE>java GsonTester
Verify the output.
{"rollNo":1,"name":{"firstName":"Mahesh","lastName":"Kumar"}} Roll No: 1 First Name: Mahesh Last Name: Kumar {"firstName":"Mahesh","lastName":"Kumar"} class Student$Name First Name: Mahesh Last Name: Kumar
Student student = new Student(); student.setRollNo(1); Student.Name name = new Student.Name(); name.firstName = "Mahesh"; name.lastName = "Kumar"; student.setName(name); //serialize static inner class object String nameString = gson.toJson(name); System.out.println(nameString); //deserialize static inner class object name = gson.fromJson(nameString,Student.Name.class); System.out.println(name.getClass());
Let's see an example of serialization/de-serialization of class with a static inner class in action. Create a Java class file named GsonTester in C:\>GSON_WORKSPACE.
File − GsonTester.java
import com.google.gson.Gson; public class GsonTester { public static void main(String args[]) { Student student = new Student(); student.setRollNo(1); Student.Name name = new Student.Name(); name.firstName = "Mahesh"; name.lastName = "Kumar"; student.setName(name); Gson gson = new Gson(); String jsonString = gson.toJson(student); System.out.println(jsonString); student = gson.fromJson(jsonString, Student.class); System.out.println("Roll No: "+ student.getRollNo()); System.out.println("First Name: "+ student.getName().firstName); System.out.println("Last Name: "+ student.getName().lastName); String nameString = gson.toJson(name); System.out.println(nameString); name = gson.fromJson(nameString,Student.Name.class); System.out.println(name.getClass()); System.out.println("First Name: "+ name.firstName); System.out.println("Last Name: "+ name.lastName); } } class Student { private int rollNo; private Name name; public int getRollNo() { return rollNo; } public void setRollNo(int rollNo) { this.rollNo = rollNo; } public Name getName() { return name; } public void setName(Name name) { this.name = name; } static class Name { public String firstName; public String lastName; } }
Compile the classes using javac compiler as follows −
C:\GSON_WORKSPACE>javac GsonTester.java
Now run the GsonTester to see the result −
C:\GSON_WORKSPACE>java GsonTester
Verify the output.
{"rollNo":1,"name":{"firstName":"Mahesh","lastName":"Kumar"}} Roll No: 1 First Name: Mahesh Last Name: Kumar {"firstName":"Mahesh","lastName":"Kumar"} class Student$Name First Name: Mahesh Last Name: Kumar
Gson performs the serialization/deserialization of objects using its inbuilt adapters. It also supports custom adapters. Let’s discuss how you can create a custom adapter and how you can use it.
Create a custom adapter by extending the TypeAdapter class and passing it the type of object targeted. Override the read and write methods to do perform custom deserialization and serialization respectively.
class StudentAdapter extends TypeAdapter<Student> { @Override public Student read(JsonReader reader) throws IOException { ... } @Override public void write(JsonWriter writer, Student student) throws IOException { } }
Register the custom adapter using GsonBuilder and create a Gson instance using GsonBuilder.
GsonBuilder builder = new GsonBuilder(); builder.registerTypeAdapter(Student.class, new StudentAdapter()); Gson gson = builder.create();
Gson will now use the custom adapter to convert Json text to object and vice versa.
String jsonString = "{\"name\":\"Mahesh\", \"rollNo\":1}"; Student student = gson.fromJson(jsonString, Student.class); System.out.println(student); jsonString = gson.toJson(student); System.out.println(jsonString);
Let's see an example of custom type adapter in action. Create a Java class file named GsonTester in C:\>GSON_WORKSPACE.
File − GsonTester.java
import java.io.IOException; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.TypeAdapter; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; import com.google.gson.stream.JsonWriter; public class GsonTester { public static void main(String args[]) { GsonBuilder builder = new GsonBuilder(); builder.registerTypeAdapter(Student.class, new StudentAdapter()); builder.setPrettyPrinting(); Gson gson = builder.create(); String jsonString = "{\"name\":\"Mahesh\", \"rollNo\":1}"; Student student = gson.fromJson(jsonString, Student.class); System.out.println(student); jsonString = gson.toJson(student); System.out.println(jsonString); } } class StudentAdapter extends TypeAdapter<Student> { @Override public Student read(JsonReader reader) throws IOException { Student student = new Student(); reader.beginObject(); String fieldname = null; while (reader.hasNext()) { JsonToken token = reader.peek(); if (token.equals(JsonToken.NAME)) { //get the current token fieldname = reader.nextName(); } if ("name".equals(fieldname)) { //move to next token token = reader.peek(); student.setName(reader.nextString()); } if("rollNo".equals(fieldname)) { //move to next token token = reader.peek(); student.setRollNo(reader.nextInt()); } } reader.endObject(); return student; } @Override public void write(JsonWriter writer, Student student) throws IOException { writer.beginObject(); writer.name("name"); writer.value(student.getName()); writer.name("rollNo"); writer.value(student.getRollNo()); writer.endObject(); } } class Student { private int rollNo; private String name; public int getRollNo() { return rollNo; } public void setRollNo(int rollNo) { this.rollNo = rollNo; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String toString() { return "Student[ name = "+name+", roll no: "+rollNo+ "]"; } }
Compile the classes using javac compiler as follows −
C:\GSON_WORKSPACE>javac GsonTester.java
Now run the GsonTester to see the result −
C:\GSON_WORKSPACE>java GsonTester
Verify the output.
Student[ name = Mahesh, roll no: 1] { "name": "Mahesh", "rollNo": 1 }
Gson by default generates optimized Json content ignoring the NULL values. But GsonBuilder provides flags to show NULL values in the Json output using the GsonBuilder.serializeNulls() method.
GsonBuilder builder = new GsonBuilder(); builder.serializeNulls(); Gson gson = builder.create();
Create a Java class file named GsonTester in C:\>GSON_WORKSPACE.
import com.google.gson.Gson; public class GsonTester { public static void main(String args[]) { Gson gson = new Gson(); Student student = new Student(); student.setRollNo(1); String jsonString = gson.toJson(student); System.out.println(jsonString); student = gson.fromJson(jsonString, Student.class); System.out.println(student); } } class Student { private int rollNo; private String name; public int getRollNo() { return rollNo; } public void setRollNo(int rollNo) { this.rollNo = rollNo; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String toString() { return "Student[ name = "+name+", roll no: "+rollNo+ "]"; } }
Compile the classes using javac compiler as follows −
C:\GSON_WORKSPACE>javac GsonTester.java
Now run the GsonTester to see the result −
C:\GSON_WORKSPACE>java GsonTester
Verify the output.
{"rollNo": 1} Student[ name = null, roll no: 1]
Create a Java class file named GsonTester in C:\>GSON_WORKSPACE.
import com.google.gson.Gson; import com.google.gson.GsonBuilder; public class GsonTester { public static void main(String args[]) { GsonBuilder builder = new GsonBuilder(); builder.serializeNulls(); builder.setPrettyPrinting(); Gson gson = builder.create(); Student student = new Student(); student.setRollNo(1); String jsonString = gson.toJson(student); System.out.println(jsonString); student = gson.fromJson(jsonString, Student.class); System.out.println(student); } } class Student { private int rollNo; private String name; public int getRollNo() { return rollNo; } public void setRollNo(int rollNo) { this.rollNo = rollNo; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String toString() { return "Student[ name = "+name+", roll no: "+rollNo+ "]"; } }
Compile the classes using javac compiler as follows −
C:\GSON_WORKSPACE>javac GsonTester.java
Now run the GsonTester to see the result −
C:\GSON_WORKSPACE>java GsonTester
Verify the output.
{ "rollNo": 1, "name": null } Student[ name = null, roll no: 1]
Gson provides @Since annotation to control the Json serialization/deserialization of a class based on its various versions. Consider the following class with versioning support. In this class, we've initially defined two variables rollNo and name and later on, we added verified as a new variable. Using @Since, we've defined rollNo and name as of version 1.0 and verified to be of version 1.1.
class Student { @Since(1.0) private int rollNo; @Since(1.0) private String name; @Since(1.1) private boolean verified; }
GsonBuilder provides the setVersion() method to serialize such versioned class.
GsonBuilder builder = new GsonBuilder(); builder.setVersion(1.0); Gson gson = builder.create();
Let's see an example of versioning support in action. Create a Java class file named GsonTester in C:\>GSON_WORKSPACE.
import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.annotations.Since; public class GsonTester { public static void main(String args[]) { GsonBuilder builder = new GsonBuilder(); builder.setVersion(1.0); Gson gson = builder.create(); Student student = new Student(); student.setRollNo(1); student.setName("Mahesh Kumar"); student.setVerified(true); String jsonString = gson.toJson(student); System.out.println(jsonString); gson = new Gson(); jsonString = gson.toJson(student); System.out.println(jsonString); } } class Student { @Since(1.0) private int rollNo; @Since(1.0) private String name; @Since(1.1) private boolean verified; public int getRollNo() { return rollNo; } public void setRollNo(int rollNo) { this.rollNo = rollNo; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void setVerified(boolean verified) { this.verified = verified; } public boolean isVerified() { return verified; } }
Compile the classes using javac compiler as follows −
C:\GSON_WORKSPACE>javac GsonTester.java
Now run the GsonTester to see the result −
C:\GSON_WORKSPACE>java GsonTester
Verify the output.
{"rollNo":1,"name":"Mahesh Kumar"} {"rollNo":1,"name":"Mahesh Kumar","verified":true}
By default, GSON excludes transient and static fields from the serialization/deserialization process. Let’s take a look at the following example.
Create a Java class file named GsonTester in C:\>GSON_WORKSPACE.
File − GsonTester.java
import com.google.gson.Gson; import com.google.gson.GsonBuilder; public class GsonTester { public static void main(String args[]) { GsonBuilder builder = new GsonBuilder(); Gson gson = builder.create(); Student student = new Student(); student.setRollNo(1); student.setName("Mahesh Kumar"); student.setVerified(true); student.setId(1); student.className = "VI"; String jsonString = gson.toJson(student); System.out.println(jsonString); } } class Student { private int rollNo; private String name; private boolean verified; private transient int id; public static String className; public int getRollNo() { return rollNo; } public void setRollNo(int rollNo) { this.rollNo = rollNo; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void setVerified(boolean verified) { this.verified = verified; } public boolean isVerified() { return verified; } public int getId() { return id; } public void setId(int id) { this.id = id; } }
Compile the classes using javac compiler as follows −
C:\GSON_WORKSPACE>javac GsonTester.java
Now run the GsonTester to see the result −
C:\GSON_WORKSPACE>java GsonTester
Verify the output
{"rollNo":1,"name":"Mahesh Kumar","verified":true}
GsonBuilder provides control over excluding fields with particular modifier using excludeFieldsWithModifiers() method from serialization/deserialization process. See the following example.
Create a Java class file named GsonTester in C:\>GSON_WORKSPACE.
File − GsonTester.java
import java.lang.reflect.Modifier; import com.google.gson.Gson; import com.google.gson.GsonBuilder; public class GsonTester { public static void main(String args[]) { GsonBuilder builder = new GsonBuilder(); builder.excludeFieldsWithModifiers(Modifier.TRANSIENT); Gson gson = builder.create(); Student student = new Student(); student.setRollNo(1); student.setName("Mahesh Kumar"); student.setVerified(true); student.setId(1); student.className = "VI"; String jsonString = gson.toJson(student); System.out.println(jsonString); } } class Student { private int rollNo; private String name; private boolean verified; private transient int id; public static String className; public int getRollNo() { return rollNo; } public void setRollNo(int rollNo) { this.rollNo = rollNo; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void setVerified(boolean verified) { this.verified = verified; } public boolean isVerified() { return verified; } public int getId() { return id; } public void setId(int id) { this.id = id; } }
Compile the classes using javac compiler as follows −
C:\GSON_WORKSPACE>javac GsonTester.java
Now run the GsonTester to see the result −
C:\GSON_WORKSPACE>java GsonTester
Verify the output
{"rollNo":1,"name":"Mahesh Kumar","verified":true,"className":"VI"}
Gson provides @Expose annotation to control the Json serialization/deserialization of a class based on its scope. Consider the following class with a variable having @Expose support. In this class, name and rollno variables are to be exposed for serialization. Then we've used the GsonBuilder.excludeFieldsWithoutExposeAnnotation() method to indicate that only exposed variables are to be serialized/deserialized. See the following example.
Create a Java class file named GsonTester in C:\>GSON_WORKSPACE.
File − GsonTester.java
import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.annotations.Expose; public class GsonTester { public static void main(String args[]) { GsonBuilder builder = new GsonBuilder(); builder.excludeFieldsWithoutExposeAnnotation(); Gson gson = builder.create(); Student student = new Student(); student.setRollNo(1); student.setName("Mahesh Kumar"); student.setVerified(true); student.setId(1); student.className = "VI"; String jsonString = gson.toJson(student); System.out.println(jsonString); } } class Student { @Expose private int rollNo; @Expose private String name; private boolean verified; private int id; public static String className; public int getRollNo() { return rollNo; } public void setRollNo(int rollNo) { this.rollNo = rollNo; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void setVerified(boolean verified) { this.verified = verified; } public boolean isVerified() { return verified; } public int getId() { return id; } public void setId(int id) { this.id = id; } }
Compile the classes using javac compiler as follows −
C:\GSON_WORKSPACE>javac GsonTester.java
Now run the GsonTester to see the result −
C:\GSON_WORKSPACE>java GsonTester
Verify the output
{"rollNo":1,"name":"Mahesh Kumar"}