JSON parsing in java - JSON endoding and decoding in java


In previous post we discussed JSON is future of web centric application development . JSON is future, so better learn it and use it seamlessly in development process.The main agenda of this post is learn how do we process JSON document(Read and write operation in JSON) in java. As we know JSON is subset of javaScript so javaScript has inbuilt support for parsing JSON. In javascript we can parse JSON like this:
var employeeArray = '{ "employees" : [' +
'{ "firstName":"Nikhl" , "lastName":"ranjan" },' +
'{ "firstName":"Rakesh" , "lastName":"Jha" },' +
'{ "firstName":"Rahul" , "lastName":"jain" } ]}';

var employeesObject = JSON.parse(employeeArray); 
employeesObject.employees[1].firstName //It displays Rakesh(0 index base array)
However, other language like java, python.etc either has to provide inbuilt support for it as part of the language or uses third party library for it. Java 7 has package "javax.json" which provides an object model API to process JSON. i.e: It provides inbuilt support for JSON parsing and object creation. JSON parsing using java 7 javax.json interface has been discussed here.
There are various third party library(jars) available for JSON parsing/decoding in java, which jars we should use depends on what we want to do with JSON - just read the attribute values or map JSON to some Model class. We will start with how to do encoding/decoding using JSON.simple followed by use of GSON and Jackson
Lets create a Json file input.json and do copy/paste following in it.We will do processing of this json in following section.
Hide code lines
{
  "employees":[
    {
      "employeeName":"Nikhil",
      "Designation":"SE",
      "empId":"101",
      "salaryComponent":[
        {
          "baseSalary":"1000",
          "hra":"300",
          "pfDeduct":"200",
          "spclAllowance":"3000"
        }
      ],
      "takeHomeSal":"4100"
    },
    {
      "employeeName":"Ranjan",
      "Designation":"SSE",
      "empId":"102",
      "salaryComponent":[
        {
          "baseSalary":"2000",
          "hra":"300",
          "pfDeduct":"200",
          "spclAllowance":"4000"
        }
      ],
      "takeHomeSal":"6100"
    }
  ]
} 

1. JSON.simple(org.json.simple):- 

JSON.simple is a simple Java toolkit for JSON. It has full support for encoding or decoding JSON text.There is a direct mapping between JSON data types(string, boolean, number, null, array and object) and Java entities like(java.lang.String, java.lang.Number, etc).JSON array is mapped to java.util.List and object is mapped to java.util.Map.Here is complete list of mapping and other features related to JSON.simple.
Download org.json.simple jar from here and place downloaded jar in class path or if you are using any IDE like eclipse create a java project and go to Build path and add this downloaded jar as external jar.Create a java file and do copy/paste following sample code lines.
Parsing/decoding of JSON:-
Hide code lines
package com.sample.json;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

public class JSONParsing {

public static void main(String[] args) {
 String employeeString = "{\"name\": \"Nikhil\",\"Organization\":"
   + "\"xyz\",\"skills\":\"Java\"}";
 // 1. Parse Input string and display Organization name of nikhil
 readStringAndParse(employeeString);
 // 2. Parse Input file and display employee name of first employee
 readInputFileAndParse();
}

public static void readStringAndParse(String employeeString) {
 JSONObject jsonObject = (JSONObject) JSONValue.parse(employeeString);
 // Check whether jsonObject contains key "Organization"
 if (jsonObject.containsKey("skills")) { // Get Organization value
  System.out.println(jsonObject.get("Organization"));
 }
}

public static void readInputFileAndParse() {
 // Read input file from resources folder.
 ClassLoader classLoader = JSONParsing.class.getClassLoader();
 File inputFile = new File(classLoader.getResource(
   "resources/input.json").getFile());
 // Create JSON parser Object
 JSONParser parser = new JSONParser();
 Object obj;
 try {
  // parse input file
  obj = parser.parse(new FileReader(inputFile));
  // Type cast Object into JSONObject
  JSONObject inputTestDataObject = (JSONObject) obj;
  // get employees array from JSONObject
  JSONArray empList = (JSONArray) inputTestDataObject
    .get("employees");
  // Display employeeName of first Object- get(0)
  System.out.println(((JSONObject) empList.get(0))
    .get("employeeName"));
 } catch (IOException | ParseException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 }
}

}
Sample output: Execute above program and you should see following in your console.
-----------------------------------
xyz
Nikhil
-----------------------------------
Lets walk through the code, method readStringAndParse(String ) creates JSONObject using JSONValue.parse(String). JSONObject behaves as java Map and using get(key) we display organization name.Similarly , in readInputFileAndParse() we read input file present in resource folder and instead of using JSONValue here we are creating object of JSONParser and pareses input file. From JSONObject we get employees array using get(key) and refer to first object of array(imagine java List) using get(index) and finally from that object we retrieve employeeName.Please go through the code once more and see the structure of JSON. it's JSON structure which drives how to parse JSON. Sample code related to advance features of JSON.simple like Container factory and SAX-like content handler can be find here.   
Creating JSON/Encoding of JSON:-
Encoding of JSON means we will create JSON object/stream and similar to wthat we read from input file while parsing. Let's create a new method inside above class and copy/paste following code.
Hide code lines
public static void encodeJSONUnordered() {
  JSONObject empObj = new JSONObject();
  empObj.put("employeeName", "Nikhil");
  empObj.put("Designation", "SSE");
  empObj.put("empId", new Integer(1000));
  
  //Create salary Object and add key/values
  JSONObject salObject = new JSONObject();
  salObject.put("baseSalary", new Double(1000));
  salObject.put("hra", new Double(300));
  salObject.put("pfDeduct", new Double(200));
  salObject.put("spclAllowance", new Double(3000));
  
  //Salary component as array, add salObj in it
  JSONArray salList = new JSONArray();
  salList.add(salObject);
  
  //add salList to main
  empObj.put("salaryComponent", salList);
  
  //last key/value entry of employeeObject
  empObj.put("takeHomeSal", new Double(200));
  
  //Create an employeeArray and
  //Add employee Object in it
  JSONArray employeeArray = new JSONArray();
  employeeArray.add(empObj);
  
  //Outcome is unOrdered,
  //order of key/value is not preserved.
  System.out.println("{\"employees\":"+employeeArray + "}");
 }
Here we are trying to create "employees" JSON structure mentioned above. As we know JSONObject is mapped to java.util.map and JSONArray is mapped to java.util.list, keep these two thing in mind  try to create object(map) and array(list) and add them as per JSON doc structure. In above sample code, first we created an empObj(It is java map) and added name, designation and id as key directly to it. This empObj contains an array(java List) and in turn JSONobjct is element of this list. so create an salobject and add key/value pairs and add this salObj(map) to salList. And finally, add this salList to empObject. Now we created and employee.
Sample output:- When you call this method from main() ,you will get this in console:
--------------------------------------------------------------------------------------------9999999999
{"employees":[{"takeHomeSal":200.0,"empId":1000,"salaryComponent":[{"pfDeduct":200.0,"baseSalary":1000.0,"spclAllowance":3000.0,"hra":300.0}],"Designation":"SSE","employeeName":"Nikhil"}]}
----------------------------------------------------------------------------------------------
We can easily spot from sample output that order of insertion not retained, reason is obvious. JSONObject (mapped to java map and java map does not maintain order of element).
How do we maintain order of insertion in JSON?
For doing this we have to use java LinkedHashMap, since it maintains order of element insertion.Create a new method and copy/paste below code in it and verify the differences in sample output:
Hide code lines
public static void encodeJSONOrdered() {
  LinkedHashMap<String, Object> mapOrdered = 
    new LinkedHashMap<>();
  mapOrdered.put("employeeName", "Nikhil");
  mapOrdered.put("Designation", "SSE");
  mapOrdered.put("empId", new Integer(1000));
  JSONValue.toJSONString(mapOrdered);
  // Create salary Object and add key/values
  JSONObject salObject = new JSONObject();
  salObject.put("baseSalary", new Double(1000));
  salObject.put("hra", new Double(300));
  salObject.put("pfDeduct", new Double(200));
  salObject.put("spclAllowance", new Double(3000));

  // Salary component as array, add salObj in it
  JSONArray salList = new JSONArray();
  salList.add(salObject);

  // add salList to main
  mapOrdered.put("salaryComponent", salList);

  // last key/value entry of employeeObject
  mapOrdered.put("takeHomeSal", new Double(200));

  // Create an employeeArray and
  // Add employee Object in it
  JSONArray employeeArray = new JSONArray();
  employeeArray.add(mapOrdered);
  String output ="{employees:"+employeeArray + "}";
  
  // Outcome is Ordered,
  // order of key/value is preserved.
  System.out.println(output);
 }
LinkedHashMap has been used in this method to maintain insertion order.LinkedHashMap maintains a linked-list to store the elements and maintain sequence of insertion. Read How does LlinkedHashMap works internally?.
Sample Output: When we execute above method from main we notice that order of insertion is maintained.
---------------------------------------------------------
{"employees":[{"employeeName":"Nikhil","Designation":"SSE","empId":1000,"salaryComponent":[{"pfDeduct":200.0,"baseSalary":1000.0,"spclAllowance":3000.0,"hra":300.0}],"takeHomeSal":200.0}]}
---------------------------------------------------------
JSON object/array can also be streamed using StringWriter (concrete implementation that uses a StringBuilder/string). Here is the sample code for that.
JSONObject obj = new JSONObject();
......fill that object
StringWriter out = new StringWriter();
obj.writeJSONString(out); //SOP(obj) will display JSON.
For more JSON encoding sample code refer this. In next post we will see how to use google GSON and Jackson for JSON serialisation / de-serialisation (map JSON with model class).
Next: JSON- serialisation / de-serialisation with GSON and Jackson

3 Comments

Previous Post Next Post