o7planning

Java JSON Processing API Tutorial (JSONP)

  1. What is JSON?
  2. JSON Parser Libraries
  3. Json Processing API
  4. Create Maven Project
  5. JSON-P Overview
  6. JSON-P Example
  7. JsonWriter Example
  8. JsonParser Example

1. What is JSON?

JSON (JavaScript Object Notation) is a data-structured text, its elements are a pair of keys and values, its value could also be another element (key & value) , values can also be an array.
This is a structure of JSON data:
{
"name" : "Tran",
"address" : "Hai Duong, Vietnam",
"phones" : [0121111111, 012222222]
}
Example with nested key-value pairs:
{
 "id": 111 ,
 "name":"Microsoft",
 "websites": [
    "http://microsoft.com",
    "http://msn.com",
    "http://hotmail.com"
 ],
 "address": {
    "street":"1 Microsoft Way",
    "city":"Redmond"
 }
}

2. JSON Parser Libraries

There are many open source Java libraries which help you to parse the Json data. Below is a list of library like so:
  • json.org
  • Jackson
  • Google GSON
  • json-lib
  • javax json
  • json-simple
  • json-smart
  • flexjson
  • fastjson

3. Json Processing API

JSON Processing (JSR-353) API is introduced in specification of Java EE 7 , which means that its libraries is available on the Web Server compatible with Java EE 7. You can also download these libraries or using Maven.
With Maven:
<!-- http://mvnrepository.com/artifact/org.glassfish/javax.json -->
<dependency>
   <groupId>org.glassfish</groupId>
   <artifactId>javax.json</artifactId>
   <version>1.0.4</version>
</dependency>
JSON-P is divided into two core APIs:
  • API Streaming (javax.json.stream),
  • JSON API Object Model (javax.json).
Streaming API is used to parse the JSON document browser from top to bottom, and emit events when it analyzes each element of the document. This API is suitable for the parse of large JSON documents, because it does not store data on memory.

The API Object Model, is simple and easy to use API , because it uses API Streaming to read the entire JSON document and generates objects in memory tree structure. This API is suitable for the parsing small JSON documents.

4. Create Maven Project

You can quickly create a Maven project and declare the use of JSON-P library
Maven library:
<!-- http://mvnrepository.com/artifact/org.glassfish/javax.json -->
<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>javax.json</artifactId>
    <version>1.0.4</version>
</dependency>
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
 http://maven.apache.org/xsd/maven-4.0.0.xsd">

 <modelVersion>4.0.0</modelVersion>

 <groupId>org.o7planning</groupId>
 <artifactId>JSONPTutorial</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <packaging>jar</packaging>

 <name>JSONPTutorial</name>
 <url>http://maven.apache.org</url>

 <properties>
   <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 </properties>

 <dependencies>


   <dependency>
     <groupId>junit</groupId>
     <artifactId>junit</artifactId>
     <version>3.8.1</version>
     <scope>test</scope>
   </dependency>
   
   <!-- http://mvnrepository.com/artifact/org.glassfish/javax.json -->
   <dependency>
       <groupId>org.glassfish</groupId>
       <artifactId>javax.json</artifactId>
       <version>1.0.4</version>
   </dependency>
   
   
 </dependencies>

</project>

5. JSON-P Overview

Some important interfaces of JSON API are:
Interface
Description
javax.json.JsonReader
You can use this to read JSON object or an array to JsonObject. And get JsonReader from Json class or JsonReaderFactory.
javax.json.JsonWriter
You can use this to write JSON object to output stream.
javax.json.stream.JsonParser
This works as a full parser and provide streaming support for reading JSON objects.
javax.json.stream.JsonGenerator
You can use this to write JSON object to output source in streaming way.
javax.json.Json
This is the factory class for creating JSON processing objects. This class provides the most commonly used methods for creating these objects and their corresponding factories. The factory classes provide all the various ways to create these objects.

6. JSON-P Example

Here is a JSON data file:
company.txt
{
  "id": 111 ,
  "name":"Microsoft",
  "websites": [
     "http://microsoft.com",
     "http://msn.com",
     "http://hotmail.com"
  ],
  "address":{
     "street":"1 Microsoft Way",
     "city":"Redmond"
  }
}

Note: The name of the attribute should be placed in the "" (quotes), for example:

  • "Id": 111

Sometimes JSON data have attributes are not named in the quotes, some JSON parsers understand and allow that, however the JSON-P parser does not allow, if you use Java JSON-P to parse a JSON data that attribute's name is not in the quotes, you'll get an exception:

javax.json.stream.JsonParsingException: Unexpected char 105 at (line no=xx, column no=xx, offset=xx)
Address.java
package org.o7planning.jsonptutorial.beans;

public class Address {
   
   private String street;
   private String city;

   public Address() {

   }

   public Address(String street, String city) {
       this.street = street;
       this.city = city;
   }

   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;
   }

   @Override
   public String toString() {
       return street + ", " + city;
   }
   
}
Company.java
package org.o7planning.jsonptutorial.beans;

public class Company {

   private int id;
   private String name;
   private String[] websites;
   private Address address;

   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 String[] getWebsites() {
       return websites;
   }

   public void setWebsites(String[] websites) {
       this.websites = websites;
   }

   public Address getAddress() {
       return address;
   }

   public void setAddress(Address address) {
       this.address = address;
   }

   @Override
   public String toString() {
       StringBuilder sb = new StringBuilder();

       sb.append("\n id:" + this.id);
       sb.append("\n name:" + this.name);
       if (this.websites != null) {
           sb.append("\n website: ");
           for (String website : this.websites) {
               sb.append(website + ", ");
           }
       }
       if (this.address != null) {
           sb.append("\n address:" + this.address.toString());
       }
       return sb.toString();
   }

}
JsonReader is an object used to read JSON data, you can get the JsonReader from Json class or from JsonReaderFactory.
InputStream input = new FileInputStream("company.txt");
 
// Create JsonReader object from Json class.
JsonReader jsonReader1 = Json.createReader(input);

// Or from Factory
JsonReaderFactory factory = Json.createReaderFactory(null);
JsonReader jsonReader2 = factory.createReader(input);
JsonReaderExample.java
package org.o7planning.jsonptutorial;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonObject;
import javax.json.JsonReader;
import javax.json.JsonValue;

import org.o7planning.jsonptutorial.beans.Address;
import org.o7planning.jsonptutorial.beans.Company;

public class JsonReaderExample {
 
  public static void main(String[] args) throws IOException {
      InputStream input = new FileInputStream("company.txt");
     
      // Create JsonReader object
      JsonReader jsonReader = Json.createReader(input);
   
     
      // Get JsonObject (root object).
      JsonObject rootJSON = jsonReader.readObject();
     
      // Close resources
      jsonReader.close();
      input.close();
     
      // Create empty Company object.
      Company company = new Company();
     
      company.setId(rootJSON.getInt("id"));
      company.setName(rootJSON.getString("name"));
     
     
      // Reading websites array from json
      JsonArray jsonArray = rootJSON.getJsonArray("websites");
      String[] websites = new String[jsonArray.size()];
     
      int index = 0;
      for(JsonValue value : jsonArray){
          websites[index++] = value.toString() ;
      }
      company.setWebsites(websites);
     
      // Reading inner object from json object.
      JsonObject addressJSON = rootJSON.getJsonObject("address");
      Address address = new Address();
      address.setStreet(addressJSON.getString("street"));
      address.setCity(addressJSON.getString("city"));
   
      company.setAddress(address);
     
      // Print out information
      System.out.println(company);
     
  }

}
Run the example:

7. JsonWriter Example

JsonWriterExample.java
package org.o7planning.jsonptutorial;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;

import javax.json.Json;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObject;
import javax.json.JsonObjectBuilder;
import javax.json.JsonWriter;

import org.o7planning.jsonptutorial.beans.Address;
import org.o7planning.jsonptutorial.beans.Company;

public class JsonWriterExample {

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

      Company company = createCompany();

      // Object Builder
      JsonObjectBuilder companyBuilder = Json.createObjectBuilder();
     
      // Object Builder
      JsonObjectBuilder addressBuilder = Json.createObjectBuilder();
     
      // Array Builder
      JsonArrayBuilder websitesBuilder = Json.createArrayBuilder();

      for (String website : company.getWebsites()) {
          websitesBuilder.add(website);
      }

      Address address = company.getAddress();
      addressBuilder.add("street", address.getStreet()).add("city", address.getCity() );

      companyBuilder.add("id", company.getId()).add("name", company.getName() );

      companyBuilder.add("websites", websitesBuilder);
      companyBuilder.add("address", addressBuilder);

      // Root JsonObject
      JsonObject rootJSONObject = companyBuilder.build();

      System.out.println("Root JsonObject: " + rootJSONObject);

      // Write to file
      File outFile= new File("C:/test/company2.txt");
      outFile.getParentFile().mkdirs();
     
      OutputStream os = new FileOutputStream(outFile);
      JsonWriter jsonWriter = Json.createWriter(os);
     
      jsonWriter.writeObject(rootJSONObject);
      jsonWriter.close();
  }

  public static Company createCompany() {

      Company company = new Company();
      company.setId(123);
      company.setName("Apple");

      String[] websites = { "http://apple.com"};
      company.setWebsites(websites);

      Address address = new Address();
      address.setCity("Cupertino");
      address.setStreet("1 Infinite Loop");

      company.setAddress(address);

      return company;
  }
 
}
Run the example:

8. JsonParser Example

Above you have worked with JsonReader to read content of json file, whole content of Json is objects and stored on memory, this way is only suitable when you work with small Json data. In the case of large data you should use JsonParser to parse Json data. JsonParser work similarly to SAX. JsonParser does not store read data on the memory.
On your code, it calls the next() method to JsonParser parse next element Json, it generates events when parsing one element. The parser can generate the following events:
  • START_OBJECT
  • END_OBJECT
  • START_ARRAY
  • END_ARRAY
  • KEY_NAME
  • VALUE_STRING
  • VALUE_NUMBER
  • VALUE_TRUE
  • VALUE_FALSE
  • VALUE_NULL.
Based on the name of the emitted event, and the name of the element being parsed, you can know the position being parsed, and retrieve the values there.
Methods that can be used in this case:
  • getString()
  • getInt()
  • ....
See for example:
JsonParserExample.java
package org.o7planning.jsonptutorial;

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

import javax.json.Json;
import javax.json.stream.JsonParser;

import org.o7planning.jsonptutorial.beans.Address;
import org.o7planning.jsonptutorial.beans.Company;

public class JsonParserExample {

    public static void main(String[] args) throws IOException {
        InputStream inputStream = new FileInputStream("company.txt");

        JsonParser jsonParser = Json.createParser(inputStream);


        // Create objects, their fields will be assigned values
        // each time the value is found in the events.
        Company company = new Company();
        Address address = new Address();
        
        List<String> websitesList = new ArrayList<String>();

        // Key name of JSON
        String keyName = null;
        
        while (jsonParser.hasNext()) {
            JsonParser.Event event = jsonParser.next();
            switch (event) {
            case KEY_NAME:
                keyName = jsonParser.getString();
                break;
            case VALUE_STRING:
                setStringValues(company, address, keyName, jsonParser.getString(), websitesList);
                break;
            case VALUE_NUMBER:
                setNumberValues(company, address, keyName, jsonParser.getInt());
                break;
            default:
                // No need..
            }
        }
        company.setAddress(address);
        String[] websites = new String[websitesList.size()];
        websitesList.toArray(websites);
        company.setWebsites(websites);

        // Print out
        System.out.println(company);        
        inputStream.close();
        jsonParser.close();
    }

    private static void setNumberValues(Company company, Address address, String keyName, int value) {
        if (keyName.equals("id")) {
            company.setId(value);
        } else {
            System.out.println("Unknown Key:" + keyName);
        }
    }

    private static void setStringValues(Company company, Address address, String keyName, String value,
            List<String> websiteList) {
        if (keyName.equals("name")) {
            company.setName(value);
        } else if (keyName.equals("street")) {
            address.setStreet(value);
        } else if (keyName.equals("city")) {
            address.setCity(value);
        } else if (keyName.equals("websites")) {
            websiteList.add(value);
        } else {
            System.out.println("Unknown Key=" + keyName);
        }
    }

}
Running the example: