JSON, which stands for JavaScript Object Notation, is a text-based, open standard, language independent data exchange format, primarily used to serialize/deserialize and transmit data over a network connection. JSON can have many other uses as well. But, in the arena of data exchange, it performs similar functions as XML. Java already has API support for XML, and JSON soon picked up interest. Java EE 7 embraced it into the library and standardised much of its functionality through Java Specification Request (JSR) 353. However, even prior to this core incorporation, there were several third party libraries to process, transform, serialize/deserialize or generate JSON data, such as Json-lib, fastjson, Flexjson, Jettison, Jackson, and so forth. Each has its uses under different scenario. So, Java actually never lacked support for JSON processing. But here, our specific interest lies in the core API group.
JSON and XML
When we talk of JSON, one question comes to our mind: Is it better than XML? In view of the data interchange scheme, they seem to perform similar functions. They may be similar, but they are not the same. In fact, their features are not comparable at all based on their originality. JSON is purely a data format. It is excellent for data interchange where readability for humans as well as machines is the primary concern. Now, what does this readability to a machine mean? Web servers and Web pages exchange data, right? JavaScript is rich in processing Web page logic. Most Web pages are built on it. JSON (JavaScript Object Notation) is close to JavaScript; this means that Web pages that use JavaScript can easily consume data given in JSON format. XML, on the other hand, is a bit alien when JavaScript consumability is concerned and requires cryptic parsing. Also, syntactically JSON uses fewer characters to represent data. This makes data size small and compact. For example, in JSON a item type (String/Number/Nested JSON Object) can be inferred syntactically. This lessens the parser’s effort to realize that id is a number and firstName a string. A simple JavaScript code to illustrate the idea is as follows:
obj=JSON.parse(jsonObj); obj.id==101; // true "Kenneth" // true
In the case of XML, we may want to write the JavaScript in the following manner:
obj = parseThatXMLPlease(); ppl = obj.getChildren("person"); p = ppl[0]; p.getChildren("id")[0].value() == 101 // true p.getChildren("firstname")[0].value() == "Kenneth" // true
JSON Data Format
{ "id": 101, "firstName": "Kenneth", "lastName": "Garcia", "address": { "street": "950 Tower Lane", "city": "Foster City" "state":"CA" } }
XML Data Format
<?xml version="1.0"?> <person id="101"> <firstname>Kenneth</firstname> <lastname>Garcia</lastname> <address> <street>950 Towel Lane</street> <city>Foster City</city> <state>CA</state> </address> </person>
XML (eXtensible Markup Language) is a language, a sophisticated language in its own right, to be precise. Using it as a data exchange format is just one of its side-effects. XML can organize the structuring information into metadata; the XML Schema can disambiguate the data structure properly without breaking any of its structural norms, modify an XML document using an XSL transformation document, and so on, and many more features. JSON, though picking up some of these features such as JSONPath for querying or JSON-Schema for validation, is not designed to have these characteristics. The point is, each has its own applicability and specific purpose. So, if comparison still creeps in, the basis of discrimination should be on what we need and what would be more appropriate under present circumstances.
Java API for JSON
The Java API for JSON processing primarily performs four functions: parsing, serialize/deserialize, transform, and query. There are two programming models for JSON processing, such as XML (DOM and SAX). One is called the object model and another is called the streaming model.
Object Model
The object model (JSON-P Model API) generates the data structure in a tree format. The tree is immutable and resides in memory. This makes it flexible to traverse and analyse. Because JSON output is generated by navigating through the tree, the memory footprint is high and lacks performance in comparison to streaming API. This is a specific concern when dealing with large volume of data.
One of the APIS of this model is the Builder pattern class JsonObjectBuilder. This class provides several overloaded add() methodS that can be used to include object properties along with their values to the JSON data. Some commonly used APIs in this model are as follows:
Class | Description |
Json | This is a Factory class for creating JSON processing objects |
JsonReader | This class reads JSON data from an input source and creates in-memory object model. |
JsonObjectBuilder, JsonArrayBuilder | These are Builder Pattern classes to create an object model or an array model in memory. |
JsonWriter | This class writes object model data from memory to a stream. |
JsonValue, JsonObject, JsonArray, JsonString, JsonNumber, | This class represents JSON data type values. |
A Quick Example
package org.mano.example; import java.io.InputStream; import java.net.URL; import javax.json.Json; import javax.json.JsonObject; import javax.json.JsonReader; public class JsonDemo { public static void main(String[] args) { try { URL url = new URL("http://date.jsontest.com"); InputStream in = url.openStream() JsonReader reader = Json.createReader(in); JsonObject jobj = reader.readObject(); System.out.println("Time: " + jobj.getJsonString("time")); System.out.println("Elapsed " + jobj.getJsonNumber ("milliseconds_since_epoch") + " miliseconds since epoch"); System.out.println("Date: " + jobj.getJsonString("date")); } catch (Exception ex) { System.out.println(ex); } } }
Streaming Model
The streaming model (JSON-P Streaming API), on the other hand, uses an event-based parser and does a sequential reading from a stream. The parser generates events and stops as soon an element is encountered. The element then can be processed or discarded through Java code before moving to the next element. It is faster and more efficient, but the tradeoff is it cannot access a specific JSON property directly like the object model due to sequential reading.
In the streaming model, the JsonGenerator class is the main API to generate JSON data. This data then can be written into a stream by using several overloaded write() methods. The write() method adds object properties and their values to the JSON data. Other APIs of this model are as follows:
Class | Description |
JsonParser | This interface helps in parsing read-only JSON data in a streaming way. |
JsonGenerator | This interface writes JSON data to an output source in the form of a stream. |
A Quick Example
package org.mano.example; import java.io.InputStream; import java.net.URL; import javax.json.Json; import javax.json.stream.JsonParser; import javax.json.stream.JsonParser.Event; public class JsonDemo { public static void main(String[] args) { try { URL url = new URL("http://date.jsontest.com"); InputStream in = url.openStream(); JsonParser parser = Json.createParser(in); while (parser.hasNext()) { Event event = parser.next(); if (event == Event.KEY_NAME) { switch (parser.getString()) { case "time": parser.next(); System.out.println("Time: " + parser.getString()); break; case "milliseconds_since_epoch": parser.next(); System.out.println("Elapsed " + parser.getLong() " miliseconds since epoch"); break; case "date": parser.next(); System.out.println("Date: " + parser.getString()); break; } } } } catch (Exception ex) { System.out.println(ex); } } }
Conclusion
JSON started as an alternative to XML. Soon, developers became interested due to its simple structure and easy operability. RESTful Web services extensively use JSON to format data between request and response processes. In view of data interchange, especially, when the consumer is a Web page, JSON seems a rational choice for developers.