Processing JSON data
Processing JSON data
If you use Java RESTful web service frameworks, such as JAX-RS, for building RESTful web APIs, the serialization and deserialization of the request and response messages will be taken care of by the framework. However, understanding the JSON structure and tools for processing JSON will definitely help you when the default offering by the framework does not meet your requirements. The following diagram illustrates the role of the JSON marshalling (converting Java object to JSON format) and unmarshalling components (converting JSON format to Java Object) in a typical Java RESTful web service implementation:

This section will teach you the various processing models for JSON data. By the term processing, we mean reading, writing, querying, and modifying JSON data. Two widely adopted programming models for processing JSON are as follows:
- Object model: In this model, the entire JSON data is read into memory in a tree format. This tree can be traversed, analyzed, or modified with appropriate APIs. As this approach loads the entire content in the memory first and then starts parsing, it ends up consuming more memory and CPU cycles. However, this model gives more flexibility while manipulating the content.
- Streaming model: The term streaming is very generic in meaning and can be used in many aspects. In our discussion, this term means that the data can be read or written in blocks. This model does not read the entire JSON content into the memory to get started with parsing; rather, it reads one element at a time. For each token read, the parser generates appropriate events indicating the type of token, such as the start or end of an array, or the start or end of the object and attribute values. A client can process the contents by listening for appropriate events. The most important point is that instead of letting the parser push the content to the client (push parser), the client can pull the information from the parser, as it needs (pull parser). In this model, the client is allowed to skip or stop reading contents in the middle of the process if it has finished reading the desired elements. This model is also useful when you write the content to an output source in blocks.
You may want to consider using streaming APIs in the following situations:
- When the data is huge in size, and it is not feasible to load the entire content into the memory for processing the content
- When partial processing is needed and the data model is not fully available yet
We will revisit these two parsing models while discussing tools for processing JSON later in this chapter.
Using JSR 353 – Java API for processing JSON
There are many Java-based frameworks available today for processing JSON. In this section, we will learn the APIs available in the Java EE platform for processing JSON. Java EE 7 has standardized the JSON processing APIs with Java Specification Request (JSR), that is, JSR 353 – Java API for JSON Processing. This JSR offers portable APIs to parse, generate, transform, and query the JSON data. The JSR 353 APIs can be classified into two categories on the basis of the processing model followed by the APIs:
- Object model API
- Streaming model API
Processing JSON with JSR 353 object model APIs
This category of APIs generates an in-memory tree model for JSON data and then starts processing it as instructed by the client. This is conceptually similar to the Document Object Model (DOM) API for XML.
Here is a list of the frequently used classes in the object model API of the JSR 353 specification:
Class or interface | Description |
javax.json.Json | This class is the main factory class for creating JSON processing objects, such as JsonReader and JsonWriter. |
javax.json.JsonReader | This interface reads the JSON content and generates a JSON object or array as appropriate. |
javax.json.JsonWriter | This interface writes a JSON object or array to an output source. |
javax.json.JsonObjectBuilder | This interface offers APIs for generating the JsonObject models from scratch. |
javax.json.JsonArrayBuilder | This interface offers APIs for generating JsonArray models from scratch. |
javax.json.JsonValue | This interface is the superinterface representing an immutable JSON value. The JSON value takes one of the following forms:
Generating the object model from the JSON representationThe example in this section illustrates the usage of the JSR 353 object model APIs for building an object representation of the JSON data. This example uses the JSON array of the employee objects stored in the emp-array.jsonfile as an input source. The contents of this file are listed under the Sample JSON file representing employee objects section. Let's see how we can convert the JSON content present in the file into a Java object model by using the JSR 353 object model API. As you may have guessed, the first step is to read the JSON content from the emp-array.json file and store it in an appropriate data structure. The following code snippet illustrates the APIs for reading the JSON content from the file to javax.json.JsonArray: Here is a brief description of the preceding code snippet. javax.json.Json is the factory class that we use for creating JSON processing objects. We will use this Json class to create the javax.json.JsonReader instance. The next step is to read the JSON content into an appropriate object model. As the JSON data that we use in this example holds an array of employee objects, we call readArray() on the JsonReader instance to retrieve javax.json.JsonArray. The JsonArray instance contains an ordered sequence of zero or more objects read from the input source. If the input is a JSON object, you can call readObject() on JsonReader to retrieve the JSON object that is presented in the input source. Now, let's see how to convert the JsonArray elements into specific object types. In this example, we will convert each JsonObject object present in employeeArray into the Employee object. The Employee class used in this example is shown here for your reference: The Java EE 7 platform lacks a binding feature, which does the automatic conversion of the JSON content into Java classes. There is a proposal, JSR 367: JavaTM API for JSON Binding (JSON-B) as part of Java EE 8, to provide a standard binding layer for converting Java objects into/from JSON messages, which will be discussed in the later sections. In this example, we create the Employee instance for each JsonObject object present in employeeArray. The following code snippet is a continuation of the previous example. This example converts the employeeArray array that we retrieved from the JSON input file into a list of Employee objects: The preceding code iterates over the JsonArray instance and builds the Employee instances. Let's take a closer look at the JsonArray object to understand how it stores JSON data. A JsonArray instance contains one or more javax.json.JsonValue elements, each representing an item present in the input source. Let's take a closer look at the representation of different value types in JSON.
Builds a JsonObject from a String of JSON data: ====================================== Example : package com.inayath; import javax.json.Json; import javax.json.JsonObject; import javax.json.JsonReader; import java.io.StringReader; public class ObjectExample { public static String JSON = "{\n" + " \"title\": \"JSON-Processing With Java EE\",\n" + " \"chapters\": [\n" + " \"Introduction\",\n" + " \"1. JSON and Java\",\n" + " \"2. JSON-Processing API features\",\n" + " \"3. The Java EE JSON Object model\",\n" + " \"4. The Java EE JSON Streaming model\",\n" + " \"Conclusion\"\n" + " ],\n" + " \"released\": true,\n" + " \"length\": 90,\n" + " \"sourceCode\": {\n" + " \"repositoryName\": \"JSON-Processing-with-Java-EE\",\n" + " \"url\": \"github.com/readlearncode\"\n" + " },\n" + " \"complementaryCourse\": [\n" + " {\n" + " \"title\": \"RESTful Service with JAX-RS 2.0\",\n" + " \"length\": 120\n" + " },\n" + " {\n" + " \"title\": \"Java Enterprise Edition Introduction\",\n" + " \"length\": 130\n" + " }\n" + " ],\n" + " \"notes\": null\n" + "}"; /** * Builds a JsonObject from a Stirng of JSON data. * * @return a JsonObject built from a String of JSON data */ public JsonObject loadJsonString() { JsonReader jsonReader = Json.createReader(new StringReader(JSON)); JsonObject jsonObject = jsonReader.readObject(); jsonReader.close(); return jsonObject; }
} ========================================================== Read Json file which has all json types : ==================================================================== example : import java.io.FileNotFoundException; import java.io.FileReader; import javax.json.Json; import javax.json.JsonArray; import javax.json.JsonObject; import javax.json.JsonReader; import javax.json.JsonString; import javax.json.JsonValue; import com.readlearn.Utils; public class ObjectExample4 {
public static void main(String[] args) throws FileNotFoundException { System.out.println(loadJsonObject()); }
public void traversJsonStructure(JsonValue jsonValue,String key ) {
if(key!=null) printKey(key);
switch(jsonValue.getValueType()){
case OBJECT: JsonObject obj=(JsonObject)jsonValue; obj.keySet(); break; case ARRAY: for(JsonValue value:(JsonArray)jsonValue) traversJsonStructure(value,null); break; case STRING: printValue(((JsonString)jsonValue).getString()); break; case NUMBER: break; case TRUE: break; case FALSE: break; case NULL:
}
}
private void printKey(String key) { System.out.println("key : "+key); }
private void printValue(String val) { System.out.println("value : "+val); }
public static JsonObject loadJsonObject() throws FileNotFoundException { String jsonFile = Utils.ROOT + System.getProperty("file.separator") + "jsondata-object.json"; JsonReader reader = Json.createReader(new FileReader(jsonFile)); JsonObject jsonObject = reader.readObject(); return jsonObject; }
} ==================================================================== public class Utils { public static String ROOT = "resources"; } ==================================================================== Reading jsonArray and jsonObject package com.inayath; import javax.json.*; import java.io.FileNotFoundException; import java.io.FileReader; public class ObjectExample2 { private String jsonFileArray = Utils.ROOT + System.getProperty("file.separator") + "jsondata-array.json"; private String jsonFileObject = Utils.ROOT + System.getProperty("file.separator") + "jsondata-object.json"; /** * Builds a JsonObject from a flat-file source containing Json data. * * @return a JsonObject built from the flat-file * @throws FileNotFoundException */ public JsonObject loadJsonObject() throws FileNotFoundException { JsonReader jsonreader=Json.createReader(new FileReader(jsonFileObject)); JsonObject jsonObj=jsonreader.readObject(); jsonreader.close();
return jsonObj;
} /** * Builds a JsonStructute from a flat-file source containing Json Array data. * * @return a JsonStructure built from the flat-file * @throws FileNotFoundException */ public JsonStructure loadJsonStructure() throws FileNotFoundException { JsonReader reader = Json.createReader(new FileReader(jsonFileArray)); JsonStructure jsonStructure = reader.read(); return jsonStructure; }
} ========================================== files will be placed under the resouces filder. jsondata-array.json file : -------------------------------------- [ "JSON-Processing With Java EE", "Java Enterprise Edition Introduction"
] jsondata-object.json file : -------------------------------------- { "title": "JSON-Processing With Java EE", "chapters": [ "Introduction", "1. JSON and Java", "2. JSON-Processing API features", "3. The Java EE JSON Object model", "4. The Java EE JSON Streaming model", "Conclusion" ], "released": true, "length": 90, "sourceCode": { "repositoryName": "JSON-Processing-with-Java-EE", "url": "github.com/readlearncode" }, "complementaryCourse": [ { "title": "RESTful Service with JAX-RS 2.0", "length": 120 }, { "title": "Java Enterprise Edition Introduction", "length": 130 } ], "notes": null
} |
Comments
Post a Comment