Skip to content

Parsing

Ralph Niemitz edited this page Dec 6, 2022 · 3 revisions

Parsing JSON using JSONParser

JSON data is parsed by calling a JSONParser#parse method. It will return a Java object which most closely resembles the JSON data that was used as input. Singular values are also accepted by the parser.

Meaning the following strings are considered valid JSON:

null

25.5

false

"Hello World!"

It is recommended to use this method over the constructors if you do not know the type of the input. An example of this would be a RESTful API endpoint which accepts a single object or an array of objects.

Code Example

try {

	JSONParser parser = new JSONParser();
	Object parsedObject = parser.parse(myJSONData);
	
	if(parsedObject != null) {
	
		Class<?> type = parsedObject.getClass();
		System.out.println(type.getName());
		
	} else {
	
		System.out.println("'null' is an invalid value!");
	}

} catch(JSONParseException exception) {

	exception.printStackTrace();
}

Parsing JSON using constructors

If you know exactly which type your data has you can use the constructors of JSONObject and JSONArray. These also just make a call to the JSONParser class but with the assumption that the result will either be an object or an array. This way you will not have to worry about casting. It should go without saying but trying to parse an array with the constructor of JSONObject will result in an exception being thrown and vice versa.

Code Example

try {

	JSONObject jsonObject = new JSONObject(myJSONData);
	System.out.println(jsonObject);

} catch(JSONParseException exception) {

	exception.printStackTrace();
}

Avoiding OutOfMemoryError

If you have to deal with extremely large JSON data you will very quickly run into OutOfMemoryErrors. Reason for that is most likely that you first loaded the JSON data into memory and then parsed it. Since this library mostly uses a DOM structure (which is fast CPU wise but expensive memory wise) this is a bad idea. It is better to directly parse this data as a stream without saving it in a variable somewhere.

Code Example

try(InputStreamReader myJSONDataReader = new InputStreamReader(inputStreamFromWhichIGetMyData, StandardCharsets.UTF8)) {

	JSONParser parser = new JSONParser();
	Object parsedObject = parser.parse(myJSONDataReader);
	
	if(parsedObject != null) {
	
		Class<?> type = parsedObject.getClass();
		System.out.println(type.getName());
		
	} else {
	
		System.out.println("'null' is an invalid value!");
	}

} catch(JSONParseException exception) {

	exception.printStackTrace();
}

Strict Parsing

Strict parsing is a feature that was introduced in version 2.1.0. It is meant to address a problem present within the original json-simple library which allowed the absence of colons and commas in JSON data.

This means the following JSON strings would be considered valid:

{"key":1 "key":2}

{"key" 1 "key" 2}

[1 2 3 4]

Personally I do not consider this a problem since one should be liberal with data input and conservative with data output. It does however pose a problem to someone who wants to validate JSON data. For this reason strict parsing was introduced to validate the existence of colons and commas and their position. Strict parsing can be enabled by setting the strict flag in certain constructors and JSONParser#parse overload methods to true. Doing so will make sure that a JSONParseException will be thrown if the JSON strings from before are used as input data.

Code Example

String jsonData = "{\"key\" 1 \"key\" 2}";

try {

	JSONObject jsonObj1 = new JSONObject(jsonData); // will not throw an exception

} catch(JSONParseException exception) {

	exception.printStackTrace();
}

try {

	JSONObject jsonObj2 = new JSONObject(jsonData, true); // will throw an exception

} catch(JSONParseException exception) {

	exception.printStackTrace();
}