-
Book Overview & Buying
-
Table Of Contents
Instant GSON
By :
In this section, you will learn about the top features supported by the GSON library. You will also learn about how to implement these features.
Objects in GSON are referred as types of JsonElement:

The GSON library can convert any user-defined class objects to and from the JSON representation. The Student class is a user-defined class, and GSON can serialize any Student object to JSON.
The Student.java class is as follows:
public class Student {
private String name;
private String subject;
privateint mark;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public int getMark() {
return mark;
}
public void setMark(int mark) {
this.mark = mark;
}
}The code for JavaObjectFeaturesUse.java is as follows:
import com.google.gson.Gson;
importcom.packt.chapter.vo.Student;
public class JavaObjectFeaturesUse {
public static void main(String[] args){
Gsongson = new Gson();
Student aStudent = new Student();
aStudent.setName("Sandeep");
aStudent.setMark(128);
aStudent.setSubject("Computer Science");
String studentJson = gson.toJson(aStudent);
System.out.println(studentJson);
Student anotherStudent = gson.fromJson(studentJson, Student.class);
System.out.println(anotherStudentinstanceof Student);
}
}The output of the preceding code is as follows:
{"name":"Sandeep","subject":"Computer Science","mark":128}
True
The preceding code creates a Student object with name as Sandeep, subject as Computer Science, and marks as 128. A Gson object is then instantiated and the Student object is passed in as a parameter to the toJson() method. It returns a string that has the JSON representation of the Java object. This string is printed as the first line in the console. The output JSON representation of the Student object is a collection of key/value pairs. The Java property of the Student class becomes the key in the JSON string.
In the last part of the code, the fromJson() method takes the JSON generated string as the first input parameter and Student.class as the second parameter, to convert the JSON string back to a Student Java object. The last line of the code uses an instance of Student as the second-line operator to verify whether the generated Java object by the fromJson() method is of type Student. In the console, it prints True as the output, and if we print the values, we will get the same values as in JSON.
GSON has implicit serializations for some classes, such as Java wrapper type (Integer, Long, Double, and so on), java.net.URL, java.net.URI, java.util.Date, and so on.
Let's see an example:
import java.util.Date;
import com.google.gson.Gson;
public class InbuiltSerializerFeature {
public static void main(String[] args) {
Date aDateJson = new Date();
Gsongson = new Gson();
String jsonDate = gson.toJson(aDateJson);
System.out.println(jsonDate);
}
}The output of the preceding code is as follows:
May 29, 2013 8:55:07 PM
The preceding code is serializing the Java Date class object to its JSON representation. In the preceding section, you have learned how GSON is used to serialize and deserialize objects, and how it supports custom serializers and deserializers for user-defined Java class objects. Let's see how it works.
Also, GSON provides the custom serialization feature to developers.
The following code is an example of a custom serializer:
classStudentTypeSerializer implements JsonSerializer<Student>{
@Override
publicJsonElement serialize(Student student, Type type,
JsonSerializationContextcontext) {
JsonObjectobj = new JsonObject();
obj.addProperty("studentname", student.getName());
obj.addProperty("subjecttaken", student.getSubject());
obj.addProperty("marksecured", student.getMark());
returnobj;
}
}The following code is an example of a custom deserializer:
classStudentTypeDeserializer implements JsonDeserializer<Student>{
@Override
public Student deserialize(JsonElementjsonelment, Type type,
JsonDeserializationContext context) throws JsonParseException {
JsonObjectjsonObject = jsonelment.getAsJsonObject();
Student aStudent = new Student();
aStudent.setName(jsonObject.get("studentname").getAsString());
aStudent.setSubject(jsonObject.get("subjecttaken").getAsString());
aStudent.setMark(jsonObject.get("marksecured").getAsInt());
return aStudent;
}
}The following code tests the custom serializer and deserializer:
import java.lang.reflect.Type;
import com.google.gson.Gson;
importcom.google.gson.GsonBuilder;
importcom.google.gson.JsonDeserializationContext;
importcom.google.gson.JsonDeserializer;
importcom.google.gson.JsonElement;
importcom.google.gson.JsonObject;
importcom.google.gson.JsonParseException;
importcom.google.gson.JsonSerializationContext;
importcom.google.gson.JsonSerializer;
public class CustomSerializerFeature {
public static void main(String[] args) {
GsonBuildergsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Student.class, new StudentTypeSerializer());
Gsongson = gsonBuilder.create();
Student aStudent = new Student();
aStudent.setName("Sandeep");
aStudent.setMark(150);
aStudent.setSubject("Arithmetic");
String studentJson = gson.toJson(aStudent);
System.out.println("Custom Serializer : Json String Representation ");
System.out.println(studentJson);
Student anotherStudent = gson.fromJson(studentJson, Student.class);
System.out.println("Custom DeSerializer : Java Object Creation");
System.out.println("Student Name "+anotherStudent.getName());
System.out.println("Student Mark "+anotherStudent.getMark());
System.out.println("Student Subject "+anotherStudent.getSubject());
System.out.println("is anotherStudent is type of Student "+(anotherStudentinstanceof Student));
}
}The output of the preceding code is as follows:
Custom Serializer : Json String Representation
{"studentname":"Sandeep","subjecttaken":"Arithmetic","marksecured":150}
Custom DeSerializer : Java Object Creation
Student Name Sandeep
Student Mark 150
Student Subject Arithmetic
is anotherStudent is type of Student true
The JSON representation of the serialized output of GSON is in compact format. If there is a huge collection of Java objects and each object has many properties that are serialized, their compact JSON representation is unreadable and looks ugly.
To address this issue, GsonBuilder supports pretty printing configuration, while creating a Gson object for serialization use. This pretty printing feature beautifies the JSON string output with proper tab indentation and new line breaks.
The following are some important points on the formatter:
JsonPrintFormatter and JsonCompactFormatter are two formatter types present in GSON.
JsonCompactFormatter is the default formatter for GSON.
JsonPrintFormatter is used for pretty printing and it is not exposed in the API. So it cannot be changed by the developer.
JsonPrintFormatter supports a default line length of 80 characters, two character indentations, and four character right margins.
JsonPrintFormatter can be used by calling a setPrettyPrinting() method on GsonBuilder.
Let's see an example of pretty printing:
import java.util.ArrayList;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.packt.chapter.vo.Student;
public class PrettyPrintFeature {
public static void main(String[] args) {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
List<Student> listOfStudent = new ArrayList<Student>();
Student student1 = new Student();
student1.setName("Sandeep Kumar Patel");
student1.setSubject("Arithmetic");
student1.setMark(234);
Student student2 = new Student();
student2.setName("Sangeeta Patel");
student2.setSubject("Geography");
student2.setMark(214);
listOfStudent.add(student1);
listOfStudent.add(student2);
String prettyJsonString = gson.toJson(listOfStudent);
System.out.println(prettyJsonString);
}
}The output of the previous code is as follows:
[
{
"name": "Sandeep Kumar Patel",
"subject": "Arithmetic",
"mark": 234
},
{
"name": "Sangeeta Patel",
"subject": "Geography",
"mark": 214
}
]The previous code serializes a list of students to the JSON representation. It uses the GsonBuilder class for getting a Gson object. The setPrettyPrinting() method is used to configure pretty printing .You can see that the output of the previous code is properly indented and tabbed, and is pleasant to read.
A Java nested class can be of two types:
Static nested class
Pure nested class (instance inner class)
In this section we will see how GSON handles each of these types of nested class objects.
GSON can serialize/deserialize a static nested class implicitly. No additional configuration is required.
Let's see an example of a static nested class:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
class Student{
private String studentName;
private int mark;
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public int getMark() {
return mark;
}
public void setMark(int mark) {
this.mark = mark;
}
public static class Course{
private String courseName;
private String duration;
public String getCourseName() {
return courseName;
}
public void setCourseName(String courseName) {
this.courseName = courseName;
}
public String getDuration() {
return duration;
}
public void setDuration(String duration) {
this.duration = duration;
}
}
}
public class StaticNestedClassFeature {
public static void main(String[] args) {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
Student.Course aCourse = new Student.Course();
aCourse.setCourseName("M.TECH.");
aCourse.setDuration("120 hr");
String jsonCourse = gson.toJson(aCourse);
System.out.println(jsonCourse);
Student.Course anotherCourse = gson.fromJson(jsonCourse, Student.Course.class);
System.out.println("Course : "+anotherCourse.getCourseName()+"Duration : "+anotherCourse.getDuration());
}
}The output of the previous code is as follows:
{
"courseName": "M.TECH.",
"duration": "120 hr"
}
Course : M.TECH.Duration : 120 hrIn the previous code, Course is a static nested class inside the Student class. courseName and duration are two properties, and their respective getter and setter methods are present in it. A static inner class can be instantiated in Java by calling the outer class with a dot operator. The line Student.Course aCourse = new Student.Course() is for initializing the nested class course. M.TECH. and 120 hr are two values used to instantiate it. From the output, it is evident that GSON is able to serialize the static nested class that produces the JSON representation of the Course object. The last line of the output shows that GSON has successfully deserialized it.
A pure nested class in Java can be instantiated by using the outer class object. The following code demonstrates how GSON can serialize and deserialize a pure nested Java class object:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
class Student{
private String studentName;
private int mark;
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public int getMark() {
return mark;
}
public void setMark(int mark) {
this.mark = mark;
}
public class Course{
private String courseName;
private String duration;
public String getCourseName() {
return courseName;
}
public void setCourseName(String courseName) {
this.courseName = courseName;
}
public String getDuration() {
return duration;
}
public void setDuration(String duration) {
this.duration = duration;
}
}
}
public class InstanceNestedClassFeature {
public static void main(String[] args) {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
Student outstudent = new Student();
Student.Course instanceCourse = outstudent.new Course();
instanceCourse.setCourseName("M.TECH.");
instanceCourse.setDuration("12 hr");
String jsonCourse = gson.toJson(instanceCourse);
System.out.println(jsonCourse);
Student.Course anotherCourse = gson.fromJson(jsonCourse, Student.Course.class);
System.out.println("Course : "+anotherCourse.getCourseName()+"Duration : "+anotherCourse.getDuration());
}
}The output of the previous code is as follows:
{
"courseName": "M.TECH.",
"duration": "12 hr"
}
Course : M.TECH.Duration : 12 hrIn the previous code, Course is a pure inner class with two fields and their getter and setter methods. A Course class object's instanceCourse is instantiated using the outer class object outstudent. This inner class object is put to serialization and deserialization, which produces the result on the console. During deserialization, the fromJson() method takes the second parameter as Student.Course, which helps GSON to successfully deserialize it to a nested class object.
GSON supports the conversion of Java arrays to and from the JSON representation.
Let's see an example of arrays:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class ArrayFeature {
public static void main(String[] args) {
Gson gson = new GsonBuilder().create();
int[] numberArray = {121, 23, 34, 44, 52};
String[] fruitsArray = {"apple", "oranges", "grapes"};
String jsonNumber = gson.toJson(numberArray);
String jsonString = gson.toJson(fruitsArray);
System.out.println(jsonNumber);
System.out.println(jsonString);
int [] numCollectionArray = gson.fromJson(jsonNumber, int[].class);
String[] fruitBasketArray = gson.fromJson(jsonString, String[].class);
System.out.println("Number Array Length "+numCollectionArray.length);
System.out.println("Fruit Array Length "+fruitBasketArray.length);
}
}The output of the previous code is as follows:
[121,23,34,44,52] ["apple","oranges","grapes"] Number Array Length 5 Fruit Array Length 3
The previous code shows two arrays, numberArray and fruitsArray, of type integer and string respectively. They are serialized and deserialized sequentially.
GSON supports generic-type Java class objects for serialization and deserialization using the com.google.gson.reflect.TypeToken class. The purpose of using the TypeToken class is to use the Type Erasure feature of Java generic types.
Type Erasure is the phase that occurs during compile time, where Java generic types are removed completely to produce byte code. So while deserializing a JSON string to a generic Java class, it may not be deserialized correctly.
The following code demonstrates the generic type serialization/deserialization and how the TypeToken class is used to address this issue:
import java.lang.reflect.Type;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
class StudentGeneric<T, E> {
T mark;
E name;
public T getMark() {
return mark;
}
public void setMark(T mark) {
this.mark = mark;
}
public E getName() {
return name;
}
public void setName(E name) {
this.name = name;
}
}
public class GenericTypeFeature {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
Gson gson = new Gson();
StudentGeneric<Integer, String> studGenericObj1 = new StudentGeneric<Integer, String>();
studGenericObj1.setMark(25);
studGenericObj1.setName("Sandeep");
String json = gson.toJson(studGenericObj1);
System.out.println("Serialized Output :");
System.out.println(json);
StudentGeneric<Integer, String> studGenericObj2 = gson.fromJson(json,
StudentGeneric.class);
System.out.println("DeSerialized Output :");
System.out.println("Mark : " + studGenericObj2.getMark());
Type studentGenericType = new TypeToken<StudentGeneric<Integer, String>>() {
}.getType();
StudentGeneric<Integer, String> studGenericObj3 = gson.fromJson(json,
studentGenericType);
System.out.println("TypeToken Use DeSerialized Output :");
System.out.println("Mark : " + studGenericObj3.getMark());
}
}The output of the previous code is as follows:
Serialized Output :
{"mark":25,"name":"Sandeep"}
DeSerialized Output :
Mark : 25.0
TypeToken Use DeSerialized Output :
Mark : 25In the previous code, a StudentGeneric class takes two generic parameters and has their respective getter and setter methods. A StudentGeneric class object is created using integer and string as types for mark and name. While serializing a student, mark is initialized to 25, but the deserialized output shows it as 25.0, which is an incorrect value, as the Type Erasure property removes the generic-type parameters from the class at compile time. The TypeToken class is used to resolve this problem. The getType() method returns the original class type with generic parameters, which helps GSON to correctly deserialize the object and output the correct value as 25.
GSON is also capable of serializing/deserializing null Java objects to and from the JSON representation.
Let's see an example of null objects:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class NullSupportFeature {
public static void main(String[] args) {
Gson gson = new GsonBuilder().serializeNulls().setPrettyPrinting().create();
Student aStudent = new Student();
aStudent.setName("Sandeep Kumar Patel");
aStudent.setSubject(null);
aStudent.setMark(234);
String studentJson = gson.toJson(aStudent);
System.out.println(studentJson);
Student javaStudentObject = gson.fromJson(studentJson, Student.class);
System.out.println("Student Subject "+javaStudentObject.getSubject());
System.out.println("Student Name "+javaStudentObject.getName());
}
}The output of the previous code is as follows:
{
"name": "Sandeep Kumar Patel",
"subject": null,
"mark": 234,
"gender": null
}
Student Subject null
Student Name Sandeep Kumar PatelGSON provides the versioned serialization/deserialization of Java objects to and from the JSON representation. This helps in iterative development and release of value objects. The GSON API provides a mechanism to cater to these requests for different versions of data.
Let's see an example of versioning:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.annotations.Since;
@Since(1.0)
class Student {
private String name;
private String subject;
private int mark;
@Since(1.1) private String gender;
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public int getMark() {
return mark;
}
public void setMark(int mark) {
this.mark = mark;
}
}
public class VersionSupportFeature {
public static void main(String[] args) {
Student aStudent = new Student();
aStudent.setName("Sandeep Kumar Patel");
aStudent.setSubject("Algebra");
aStudent.setMark(534);
aStudent.setGender("Male");
System.out.println("Student json for Version 1.0 ");
Gson gson = new GsonBuilder().setVersion(1.0).setPrettyPrinting().create();
String jsonOutput = gson.toJson(aStudent);
System.out.println(jsonOutput);
System.out.println("Student json for Version 1.1 ");
gson = new GsonBuilder().setVersion(1.1).setPrettyPrinting().create();
jsonOutput = gson.toJson(aStudent);
System.out.println(jsonOutput);
}
}The output of the previous code is as follows:
Student json for Version 1.0
{
"name": "Sandeep Kumar Patel",
"subject": "Algebra",
"mark": 534
}
Student json for Version 1.1
{
"name": "Sandeep Kumar Patel",
"subject": "Algebra",
"mark": 534,
"gender": "Male"
}While serializing/deserializing a Java object to and from JSONstring, GSON creates a default instance of that class using its default constructor. It is good to have a default no argument constructor of the Java class. If a class does not have a default constructor, GSON provides a class.google.gson.InstanceCreator interface implementation to deal with it.
|
Method |
Detail |
|---|---|
|
|
Parameter: Takes a parameter of type Return: A default object instance of type |
Let's see an example of a no argument constructor:
import java.lang.reflect.Type;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.InstanceCreator;
class Employee {
private String name;
private Salary salary;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Salary getSalary() {
return salary;
}
public void setSalary(Salary salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Employee [name=" + name + ", salary=" + salary + " ]";
}
}
class Salary {
private int salaryAmount;
Salary(int salary) {
this.salaryAmount = salary;
}
@Override
public String toString() {
return "Salary [salaryAmount=" + salaryAmount + "]";
}
}
class SalaryInstanceCreator implements InstanceCreator<Salary> {
@Override
public Salary createInstance(Type type) {
return new Salary(25000);
}
}
public class InstanceCreatorUse {
public static void main(String[] args) {
String jsonString = "{\"name\" :\"Sandeep\" , \"salary\": {}}";
Gson gson = new GsonBuilder().serializeNulls()
.registerTypeAdapter(Salary.class, new SalaryInstanceCreator())
.setPrettyPrinting().create();
System.out.println(gson.fromJson(jsonString, Employee.class));
}
}The previous code demonstrates a JSON string of type Employee, which is deserialized to the Employee-type class object.
Input: A JSON string
jsonString = "{\"name\" :\"Sandeep\" , \"salary\": {}}";Output: A Java object, a toString() method printed in console
Employee [name=Sandeep, salary=Salary [salaryAmount=25000]]
A class SalaryInstanceCreator is implemented using com.google.gson.InstanceCreator and overrides the createInstance() method, which returns a parameterized Salary constructor of value 25000.
This SalaryInstanceCreator is registered to GSON as registerTypeAdapter().
When GSON finds the empty salary string, it looks for the default constructor of type Salary. As default Salary constructor is not present, it looks for GsonBuilder settings for a type adapter and finds SalaryInstanceCreator. It invokes the createInstance() method.
So, while deserializing for an empty Salary class object, GSON receives 25000 as the default value.
This feature provides flexibility for the developer to give custom names while serializing Java objects. The JSON representation becomes more meaningful and readable.
GSON provides a FieldNamingPolicy class with some built-in field naming support:
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.annotations.SerializedName;
class College{
@SerializedName("instituteName")
private String name;
private String[] coursesOffer;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String[] getCoursesOffer() {
return coursesOffer;
}
public void setCoursesOffer(String[] coursesOffer) {
this.coursesOffer = coursesOffer;
}
}
public class FieldNamingFeature {
public static void main(String[] args) {
Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).setPrettyPrinting().create();
College aCollege = new College();
aCollege.setName("VIT University, Vellore");
String[] courses = {"BTECH, MTECH, BSC, MSC"};
aCollege.setCoursesOffer(courses);
String jsonCollege = gson.toJson(aCollege);
System.out.println(jsonCollege);
College anotherCollege = gson.fromJson(jsonCollege, College.class);
System.out.println("College Name : "+anotherCollege.getName);
}
}The output of the previous code is as follows:
{
"instituteName": "VIT University, Vellore",
"CoursesOffer": [
"BTECH, MTECH, BSC, MSC"
]
}
College Name : VIT University, VelloreBeyond the basic field naming feature, GSON also provides a FieldNamingStrategy class to enable developers to create their own field naming policy. The following steps demonstrate how to create a custom field naming policy:
Create a Java class implementing the FieldNamingStrategy interface.
Override the translateName() method.
This method provides the real implementation of a custom field naming strategy. GSON uses the logic inside this method for a field name while processing a custom field name strategy:
|
Method |
Detail |
|---|---|
|
|
Parameter: Takes input parameter of type Returns: Returns the changed field name as |
Let's see an example of user-defined field naming:
import java.lang.reflect.Field;
import com.google.gson.FieldNamingStrategy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
class College {
private String name;
private String[] coursesOffer;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String[] getCoursesOffer() {
return coursesOffer;
}
public void setCoursesOffer(String[] coursesOffer) {
this.coursesOffer = coursesOffer;
}
}
class CustomFieldStrategy implements FieldNamingStrategy {
@Override
public String translateName(Field aField) {
String nameOfField = aField.getName();
return nameOfField.toUpperCase();
}
}
public class CustomFieldNamingFeature {
public static void main(String[] args) {
Gson gson = new GsonBuilder()
.setFieldNamingStrategy(new CustomFieldStrategy())
.setPrettyPrinting().create();
College aCollege = new College();
aCollege.setName("VIT University, Vellore");
String[] courses = { "BTECH, MTECH, BSC, MSC" };
aCollege.setCoursesOffer(courses);
String jsonCollege = gson.toJson(aCollege);
System.out.println(jsonCollege);
}
}The output of the previous code is as follows:
{
"NAME": "VIT University, Vellore",
"COURSESOFFER": [
"BTECH, MTECH, BSC, MSC"
]
}GSON API also supports field exclusion during serialization. Developers can exclude some fields while serializing Java objects. GSON provides two different approaches to achieve field exclusion:
Configuring GsonBuilder
Using Annotation

The previous figure shows the abstract of two different approaches for field exclusion strategies in GSON. Each of these approaches is explained in detail.
GsonBuilder provides the excludeFieldsWithModifiers() method to exclude fields while serializing. This method provides the capability of excluding all class fields that have the specified modifiers .The prototype signature of this method is as follows:
public GsonBuilder excludeFieldsWithModifiers(int... modifiers)
Input Parameter: The ellipsis (...) symbol indicates that it can take any number of parameters of type java.lang.reflect.Modifier such as Modifier.STATIC, Modifier.PUBLIC, and Modifier.PRIVATE
Return Type: It returns a reference object of type GsonBuilder
Let's see an example of configuring GsonBuilder:
import java.lang.reflect.Modifier;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
class Employee {
private String name;
private transient String gender;
private static String designation;
protected String department;
public Employee() {
this("Abcd Employee", "MALE", "Tech Lead", "IT Services");
}
@SuppressWarnings("static-access")
public Employee(String name, String gender, String designation,
String department) {
this.name = name;
this.gender = gender;
this.designation = designation;
this.department = department;
}
}
public class FieldExclusionFeature {
public static void main(String[] args) {
Gson gson = new Gson();
String json = gson.toJson(new Employee("Sandeep", "Male", "Tech Lead","IT Services"));
System.out.println(json);
Gson gson2 = new GsonBuilder().excludeFieldsWithModifiers().create();
json = gson2.toJson(new Employee("Sandeep", "MALE", "Tech Lead","IT Services"));
System.out.println(json);
Gson gson3 = new GsonBuilder().excludeFieldsWithModifiers(Modifier.STATIC).create();
json = gson3.toJson(new Employee("Sandeep", "MALE", "Tech Lead","IT Services"));
System.out.println(json);
}
}The output of the previous code is as follows:
{
"name": "Sandeep",
"department": "IT Services"
} {
"name": "Sandeep",
"gender": "MALE",
"designation": "TechLead",
"department": "IT Services"
} {
"name": "Sandeep",
"gender": "MALE",
"department": "IT Services"
}We can derive three points from the previous code:
The first line of the output has an Employee JSON string with two fields: name and department. This output is due to the Gson object, which is created using the default approach. For this reason, it omits static and transient fields while serializing.
The second line of the output has an Employee JSON string with four fields: name, gender, designation, and department. This output is due to the Gson object, which is created using the builder approach and excludeFieldWithModifiers() method. As no parameters are passed, it serializes all the type of fields present in the Employee object.
The third line of the output has an Employee JSON string with three fields: name, gender, and department. The output is due to the Gson object, which is created using the builder approach, and excludeFieldsWithModifiers() method. As Modifier.STATIC is passed as a parameter to this method, it does not serialize any static field of the Employee object.
GSON provides @Expose annotation to achieve field exclusion during serialization. The field marked with @Expose notation will be serialized to the JSON representation. The GSON excludeFieldsWithoutExposeAnnotation() method must be called while configuring GsonBuilder to use @Expose annotation.
Let's see an example of using @Expose annotation:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.annotations.Expose;
class Vegetable {
private String name;
@Expose
private int price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
public class FieldExclusionAnnotationUse {
public static void main(String[] args) {
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation()
.create();
Vegetable aVegetable = new Vegetable();
aVegetable.setName("Potato");
aVegetable.setPrice(26);
String jsonVegetable = gson.toJson(aVegetable);
System.out.println("JSON Representation of Vegetable : ");
System.out.println(jsonVegetable);
}
}The output of the previous code is as follows:
JSON Representation of Vegetable :
{"price":26}We can derive the following points from the previous code:
The output of the previous code has a JSON string with a field price. This output is due to the Gson object created using the builder approach and excludeFieldsWithoutExposeAnnotation() method.
While serializing Java objects, it serializes only the fields with @Expose annotation.
GSON provides flexibility for developers to create a custom annotation for use in the exclusion of fields and classes. The following steps demonstrate how to create a custom annotation:
Declaring a marker Java interface. A marker interface is simple a Java interface without any fields or methods. In short, an empty Java interface is a marker interface. The name of this interface will be used as a custom exclusion annotation.
A Java class to implement com.google.gson.ExclusionStrategy. The ExclusionStrategy interface provides two methods. By implementing this interface, the Java class provides the functionality for custom exclusion annotation. When GSON is serializing or deserializing and finds a custom annotation, it looks at the Java class that implemented the ExclusionStrategy interface to find out what to do with it.
The ExclusionStrategy interface provides two methods:
|
Method |
Details |
|---|---|
|
|
Parameter: Takes Returns a Boolean value:
|
|
|
Parameter: Takes Returns a Boolean value:
|
Let's see an example of a user-defined field exclusion annotation:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD })
@interface MyExclude {
}
class CustomExclusionStrategy implements ExclusionStrategy {
private final Class<?> typeToExclude;
CustomExclusionStrategy(Class<?> typeToExclude) {
this.typeToExclude = typeToExclude;
}
public boolean shouldSkipClass(Class<?> classname) {
return (classname == typeToExclude);
}
public boolean shouldSkipField(FieldAttributes f) {
return f.getAnnotation(MyExclude.class) != null;
}
}
class Vegetable {
private String name;
@MyExclude
private int price;
public Vegetable() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
public class UserDefinedFieldExclusion {
public static void main(String[] args) {
Gson gson = new GsonBuilder().setExclusionStrategies(new CustomExclusionStrategy(MyExclude.class)).create();
Vegetable aVegetable = new Vegetable();
aVegetable.setName("Potato");
aVegetable.setPrice(26);
String jsonVegetable = gson.toJson(aVegetable);
System.out.println(jsonVegetable);
}
}The output of the previous code is as follows:
{"name":"Potato"}The previous code performs the following steps:
A user-defined marker annotation @MyExclude is created using the java.lang.annotation package.
A new custom exclusion strategy is created by instantiating the CustomExclusionStrategy class with the MyExclude.class parameter.
Using the setExclusionStrategies() method, GsonBuilder is configured with this new exclusion strategy.
Now the Gson object created from GsonBuilder will exclude fields with @MyExclude annotation.
After the invention of the JSON format and its companion language library GSON, the development of Java web applications where a client communicates with a server and responds with data in the JSON format, gained a lot of popularity. This made the Web 2.0 applications successful.
The following StudentJsonDataServlet.java shows how a JSON data of type Student is returned by a Java servlet and rendered as an HTML table in a browser:
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.gson.Gson;
import com.packt.myapp.data.Student;
@WebServlet("/StudentJsonDataServlet")
public class StudentJsonDataServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public StudentJsonDataServlet() {}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Gson gson = new Gson();
List<Student> listOfStudent = getStudentData();
String jsonString = gson.toJson(listOfStudent);
response.setContentType("application/json");
response.getWriter().write(jsonString);
}
/**
* Returns List of Static Student data
*/
private List<Student> getStudentData(){
Student s1 = new Student();
s1.setName("Sandeep");
s1.setSubject("Computer");
s1.setMark(85);
Student s2 = new Student();
s2.setName("John");
s2.setSubject("Science");
s2.setMark(85);
Student s3 = new Student();
s3.setName("Ram");
s3.setSubject("Computer");
s3.setMark(85);
List<Student> listOfStudent = new ArrayList<Student>();
listOfStudent.add(s1);
listOfStudent.add(s2);
listOfStudent.add(s3);
return listOfStudent;
}
}The StudentJsonDataServlet returns a list of student's details as a JSON string. To indicate to the browser, the data response is a JSON-type header that needs to be set to application/json.
The following studentstableview.html is the file for rendering the response of the servlet in the browser:
<html>
<head>
<title>Students JSON Table View</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
</head>
<body>
<div id="student-data-container"></div>
<script>
$(document).ready(function(){
var getStudentTableHtml, html,
htmlStudent, container =$('#student-data-container'),
ajaxRequest = $.ajax({
url: "StudentJsonDataServlet",
dataType: "JSON",
success: function(data){
htmlStudent = getStudentTableHtml(data);
container.html(htmlStudent)
}
}),
getStudentTableHtml = function(data){
html = [];
html.push("<TABLE border='2px' cellspacing='2px'>");
html.push("<TR>");
html.push("<TH>NAME</TH>");
html.push("<TH>SUBJECT</TH>");
html.push("<TH>MARK</TH>");
html.push("</TR>");
$.each(data,function(index, aStudent){
html.push("<TR>");
html.push("<TD>");
html.push(aStudent.name);
html.push("</TD>");
html.push("<TD>");
html.push(aStudent.subject);
html.push("</TD>");
html.push("<TD>");
html.push(aStudent.mark);
html.push("</TD>");
html.push("</TR>");
});
html.push("</TABLE>")
return html.join("");
}
})
</script>
</body>
</html>The previous code shows that a jQuery Ajax event is called on a DOM ready event. The servlet uses the GSON API to convert a list of Java student objects to its equivalent JSON representation and sends it as a response content. The Firebug console in the following screenshot shows the Ajax request and response in a JSON object:

On getting the response, jQuery calls the success handler. In return, the success handler calls the getStudentTableHtml() method to build a table in HTML.
This method uses a for loop to iterate each student JSON object to build the rows of the table. The following screenshot shows an HTML table for students' details built from the student JSON response data:

Change the font size
Change margin width
Change background colour