Gson Example Tutorial Parse JSON

Filed Under: Java

Welcome to Gson Example Tutorial. In last post we looked at the Java JSON API and you can easily tell that it’s not convenient to use it. Whether you have to convert JSON to Java Object or otherwise, you need to write a lot of code that is tightly coupled with the JSON structure.

Gson

gson, gson example tutorial, gson parse json

I started looking out for some other JSON parser API that can do the transformation itself and found about Google Gson. Gson is an open source code and it’s used a lot in working with JSON and Java. Gson uses Java Reflection to provide simple methods to convert JSON to java and vice versa.

Gson Maven

You can download Gson jar file from google code website or if you are using maven then all you need is to add it’s dependency like below.


<dependencies>
    <!--  Gson dependency -->
    <dependency>
      <groupId>com.google.code.gson</groupId>
      <artifactId>gson</artifactId>
      <version>2.2.4</version>
    </dependency>
</dependencies>

Gson is very powerful API and it supports Java Generics. Gson API also supports out of the box JSON to Java Object conversion if the object field names are same as in json. If we want to use different name for java bean and json, then we can use @SerializedName java annotation and map the variables in JSON and Java Class.

Gson Example

Let’s look at a complex Gson example that involves nested object and array in JSON and we will map it to java bean properties of type List, Map, Array etc.

employee.txt


{
  "empID": 100,
  "name": "David",
  "permanent": false,
  "address": {
    "street": "BTM 1st Stage",
    "city": "Bangalore",
    "zipcode": 560100
  },
  "phoneNumbers": [
    123456,
    987654
  ],
  "role": "Manager",
  "cities": [
    "Los Angeles",
    "New York"
  ],
  "properties": {
    "age": "28 years",
    "salary": "1000 Rs"
  }
}

Let’s create the java bean classes to convert JSON to Java Object.

Employee.java


package com.journaldev.json.model;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

import com.google.gson.annotations.SerializedName;

public class Employee {

	@SerializedName("empID")
	private int id;
	private String name;
	private boolean permanent;
	private Address address;
	private long[] phoneNumbers;
	private String role;
	private List<String> cities;
	private Map<String, String> properties;
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public boolean isPermanent() {
		return permanent;
	}
	public void setPermanent(boolean permanent) {
		this.permanent = permanent;
	}
	public Address getAddress() {
		return address;
	}
	public void setAddress(Address address) {
		this.address = address;
	}
	public long[] getPhoneNumbers() {
		return phoneNumbers;
	}
	public void setPhoneNumbers(long[] phoneNumbers) {
		this.phoneNumbers = phoneNumbers;
	}
	public String getRole() {
		return role;
	}
	public void setRole(String role) {
		this.role = role;
	}
	
	@Override
	public String toString(){
		StringBuilder sb = new StringBuilder();
		sb.append("***** Employee Details *****\n");
		sb.append("ID="+getId()+"\n");
		sb.append("Name="+getName()+"\n");
		sb.append("Permanent="+isPermanent()+"\n");
		sb.append("Role="+getRole()+"\n");
		sb.append("Phone Numbers="+Arrays.toString(getPhoneNumbers())+"\n");
		sb.append("Address="+getAddress()+"\n");
		sb.append("Cities="+Arrays.toString(getCities().toArray())+"\n");
		sb.append("Properties="+getProperties()+"\n");
		sb.append("*****************************");
		
		return sb.toString();
	}
	public List<String> getCities() {
		return cities;
	}
	public void setCities(List<String> cities) {
		this.cities = cities;
	}
	public Map<String, String> getProperties() {
		return properties;
	}
	public void setProperties(Map<String, String> properties) {
		this.properties = properties;
	}
}

Address.java


package com.journaldev.json.model;

public class Address {
	
	private String street;
	private String city;
	private int zipcode;
	
	public String getStreet() {
		return street;
	}
	public void setStreet(String street) {
		this.street = street;
	}
	public String getCity() {
		return city;
	}
	public void setCity(String city) {
		this.city = city;
	}
	public int getZipcode() {
		return zipcode;
	}
	public void setZipcode(int zipcode) {
		this.zipcode = zipcode;
	}
	
	@Override
	public String toString(){
		return getStreet() + ", "+getCity()+", "+getZipcode();
	}
}

Here is the java program showing Gson example to parse JSON.

EmployeeGsonExample.java


package com.journaldev.json.gson;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.journaldev.json.model.Address;
import com.journaldev.json.model.Employee;

public class EmployeeGsonExample {

	public static void main(String[] args) throws IOException {
		Employee emp = createEmployee();

		// Get Gson object
		Gson gson = new GsonBuilder().setPrettyPrinting().create();

		// read JSON file data as String
		String fileData = new String(Files.readAllBytes(Paths
				.get("employee.txt")));

		// parse json string to object
		Employee emp1 = gson.fromJson(fileData, Employee.class);

		// print object data
		System.out.println("\n\nEmployee Object\n\n" + emp1);

		// create JSON String from Object
		String jsonEmp = gson.toJson(emp);
		System.out.print(jsonEmp);

	}

	public static Employee createEmployee() {

		Employee emp = new Employee();
		emp.setId(100);
		emp.setName("David");
		emp.setPermanent(false);
		emp.setPhoneNumbers(new long[] { 123456, 987654 });
		emp.setRole("Manager");

		Address add = new Address();
		add.setCity("Bangalore");
		add.setStreet("BTM 1st Stage");
		add.setZipcode(560100);
		emp.setAddress(add);

		List<String> cities = new ArrayList<String>();
		cities.add("Los Angeles");
		cities.add("New York");
		emp.setCities(cities);

		Map<String, String> props = new HashMap<String, String>();
		props.put("salary", "1000 Rs");
		props.put("age", "28 years");
		emp.setProperties(props);

		return emp;
	}
}

Gson is the main class that exposes the methods fromJson() and toJson() for conversion. For default implementation, we can create this object directly or we can use GsonBuilder class that provide useful options for conversion such as pretty printing, field naming convention, excluding fields, date format etc.

When you will run above gson example program, we will get following output for java object.


Employee Object

***** Employee Details *****
ID=100
Name=David
Permanent=false
Role=Manager
Phone Numbers=[123456, 987654]
Address=BTM 1st Stage, Bangalore, 560100
Cities=[Los Angeles, New York]
Properties={age=28 years, salary=1000 Rs}
*****************************

You can see how easy it is to use Gson and that’s why Gson is a very popular java API for JSON parsing.

The above Gson example of JSON parsing is known as Object model because whole JSON is converted to object at once. Most of the times it’s enough for us but if JSON is really huge and we don’t want to have all of it in memory at once, Gson provides Streaming API too.

Gson Example Parse JSON using Streaming API

Let’s see Gson example where we will use Streaming API for json to java object conversion.

EmployeeGsonReader.java


package com.journaldev.json.gson;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.journaldev.json.model.Address;
import com.journaldev.json.model.Employee;

public class EmployeeGsonReader {

	public static void main(String[] args) throws IOException {
		InputStream is = new FileInputStream("employee.txt");
		InputStreamReader isr = new InputStreamReader(is);
		
		//create JsonReader object
		JsonReader reader = new JsonReader(isr);
		
		//create objects
		Employee emp = new Employee();
		Address add = new Address();
		emp.setAddress(add);
		List<Long> phoneNums = new ArrayList<Long>();
		emp.setCities(new ArrayList<String>());
		emp.setProperties(new HashMap<String, String>());
		String key = null;
		boolean insidePropertiesObj=false;
		
		key = parseJSON(reader, emp, phoneNums, key, insidePropertiesObj);
		
		
		long[] nums = new long[phoneNums.size()];
		int index = 0;
		for(Long l :phoneNums){
			nums[index++] = l;
		}
		emp.setPhoneNumbers(nums);
		
		reader.close();
		//print employee object
		System.out.println("Employee Object\n\n"+emp);
	}
	
	

	private static String parseJSON(JsonReader reader, Employee emp,
			List<Long> phoneNums, String key, boolean insidePropertiesObj) throws IOException {
		
		//loop to read all tokens
				while(reader.hasNext()){
					//get next token
					JsonToken token = reader.peek();
					
					switch(token){
					case BEGIN_OBJECT:
						reader.beginObject();
						if("address".equals(key) || "properties".equals(key)){
							while(reader.hasNext()){
							parseJSON(reader, emp,phoneNums, key, insidePropertiesObj);
							}
							reader.endObject();
						}
						break;
					case END_OBJECT:
						reader.endObject();
						if(insidePropertiesObj) insidePropertiesObj=false;
						break;
					case BEGIN_ARRAY:
						reader.beginArray();
						if("phoneNumbers".equals(key) || "cities".equals(key)){
							while(reader.hasNext()){
								parseJSON(reader, emp,phoneNums, key, insidePropertiesObj);
								}
							reader.endArray();
						}
						break;
					case END_ARRAY:
						reader.endArray();
						break;
					case NAME:
						key = reader.nextName();
						if("properties".equals(key)) insidePropertiesObj=true;
						break;
					case BOOLEAN:
						if("permanent".equals(key)) emp.setPermanent(reader.nextBoolean());
						else{
							System.out.println("Unknown item found with key="+key);
							//skip value to ignore it
							reader.skipValue();
						}
						break;
					case NUMBER:
						if("empID".equals(key)) emp.setId(reader.nextInt());
						else if("phoneNumbers".equals(key)) phoneNums.add(reader.nextLong());
						else if("zipcode".equals(key)) emp.getAddress().setZipcode(reader.nextInt());
						else {
							System.out.println("Unknown item found with key="+key);
							//skip value to ignore it
							reader.skipValue();
						}
						break;
					case STRING:
						setStringValues(emp, key, reader.nextString(), insidePropertiesObj);
						break;
					case NULL:
						System.out.println("Null value for key"+key);
						reader.nextNull();
						break;
					case END_DOCUMENT:
						System.out.println("End of Document Reached");
						break;
					default:
						System.out.println("This part will never execute");
						break;
						
					}
				}
				return key;
	}



	private static void setStringValues(Employee emp, String key,
			String value, boolean insidePropertiesObj) {
		if("name".equals(key)) emp.setName(value);
		else if("role".equals(key)) emp.setRole(value);
		else if("cities".equals(key)) emp.getCities().add(value);
		else if ("street".equals(key)) emp.getAddress().setStreet(value);
		else if("city".equals(key)) emp.getAddress().setCity(value);
		else{
			//add to emp properties map
			if(insidePropertiesObj){
				emp.getProperties().put(key, value);
			}else{
				System.out.println("Unknown data found with key="+key+" value="+value);
			}
			
		}
	}

}

Since JSON is a recursive language, we need to call our parsing method recursively for array and nested object. JsonToken is java enum returned by JsonReader next() method that we can use with conditional logic or switch case statements for conversion.

From the code above, you can understand that it’s not an easy implementation and if the JSON is really complex, then this code will become very hard to maintain. Avoid using it until unless there is no way to use Object based model.

Gson Example to Write Object to File

Let’s see how we can write Employee object using Gson Streaming API.

EmployeeGsonWriter.java


package com.journaldev.json.gson;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Set;

import com.google.gson.stream.JsonWriter;
import com.journaldev.json.model.Employee;

public class EmployeeGsonWriter {

	public static void main(String[] args) throws IOException {
		Employee emp = EmployeeGsonExample.createEmployee();
		
		//writing on console, we can initialize with FileOutputStream to write to file
		OutputStreamWriter out = new OutputStreamWriter(System.out);
		JsonWriter writer = new JsonWriter(out);
		//set indentation for pretty print
		writer.setIndent("\t");
		//start writing
		writer.beginObject(); //{
		writer.name("id").value(emp.getId()); // "id": 123
		writer.name("name").value(emp.getName()); // "name": "David"
		writer.name("permanent").value(emp.isPermanent()); // "permanent": false
		writer.name("address").beginObject(); // "address": {
			writer.name("street").value(emp.getAddress().getStreet()); // "street": "BTM 1st Stage"
			writer.name("city").value(emp.getAddress().getCity()); // "city": "Bangalore"
			writer.name("zipcode").value(emp.getAddress().getZipcode()); // "zipcode": 560100
			writer.endObject(); // }
		writer.name("phoneNumbers").beginArray(); // "phoneNumbers": [
			for(long num : emp.getPhoneNumbers()) writer.value(num); //123456,987654
			writer.endArray(); // ]
		writer.name("role").value(emp.getRole()); // "role": "Manager"
		writer.name("cities").beginArray(); // "cities": [
			for(String c : emp.getCities()) writer.value(c); //"Los Angeles","New York"
			writer.endArray(); // ]
		writer.name("properties").beginObject(); //"properties": {
			Set<String> keySet = emp.getProperties().keySet();
			for(String key : keySet) writer.name("key").value(emp.getProperties().get(key));//"age": "28 years","salary": "1000 Rs"
			writer.endObject(); // }
		writer.endObject(); // }
		
		writer.flush();
		
		//close writer
		writer.close();
		
	}

}

Converting java object to JSON is comparatively easy than parsing with Gson streaming API. By default JsonWriter writes json in compact form but we can set indent for pretty printing.

That’s all for Gson example tutorial, let me know if you face any issues with it. Download project from below link and play around with different options Gson provides.

References:

Google-Gson on Google Code
Gson User Guide

Comments

  1. Sameer says:

    Nice tutorial.
    But, I have a question : would it be better if we defined Address class as a static inner class in Employee class?

  2. Mayur says:

    Nice Article Pankaj but I had few queries & Suggestions as well.

    1. In EmployeeGsonExample.java file createEmployee() function why you have passed the values Statically ?
    2. It would really help new learners to understand easily & will look your article better if you post the screenshots/ video of the working app.

    1. Pankaj says:

      1. createEmployee() is a dummy method to create the employee object. It has no other value to the program.

      2. Usually I provide screenshot where it’s necessary. Here I am parsing JSON to Java Object and vice versa. There is not much benefit of having screenshot of the program output. It would be more beneficial to provide the project itself, so that you can just import it, run it, modify it and learn more. That’s why I have provided project code and not screenshots.

    2. Aaron says:

      I have the same question. It makes the explanation confusing.

  3. Aparajith says:

    Thank you very much for detailed articles, it is very much helpful.

  4. Melodi says:

    I searched for hours and attempted working through gson documentation and finally found this example. This was absolutely the best. Using gson truly is so simple. Thank you so much. It’d be cool to take it one more step to show how to loop through multiple employees using a class based list of objects.

  5. soumya says:

    very good article

  6. Philip Grove says:

    In examples remove Yoda conditions as they are likely to cause more confusion than benefit.

  7. Gibran Castillo says:

    This is really good. Do you have a tutorial similar like this one, with the addition of Hibernate and JTA.

  8. Vinay says:

    Nice article Pankaj! 🙂

  9. Pranav says:

    Good article. Keep up the good work.

  10. James says:

    Hi Pankaj,
    A good article.

    Regards,
    James.

  11. rafiq says:

    Hi Pankaj,

    I am new to Json and looking to create json in java and parse in python could you guide me in any way possible problem description is here http://stackoverflow.com/questions/23557478/create-json-in-java-and-parse-in-python
    Thanks for your time.

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages