Determine whether JSON is a JSONObject or JSONArray

AndroidArraysJsonObject

Android Problem Overview


I am going to receive either a JSON Object or Array from server, but I have no idea which it will be. I need to work with the JSON, but to do so, I need to know if it is an Object or an Array.

I am working with Android.

Does any one have a good way of doing this?

Android Solutions


Solution 1 - Android

I found better way to determine:

String data = "{ ... }";
Object json = new JSONTokener(data).nextValue();
if (json instanceof JSONObject)
  //you have an object
else if (json instanceof JSONArray)
  //you have an array

tokenizer is able to return more types: http://developer.android.com/reference/org/json/JSONTokener.html#nextValue()

Solution 2 - Android

There are a couple ways you can do this:

  1. You can check the character at the first position of the String (after trimming away whitespace, as it is allowed in valid JSON). If it is a {, you are dealing with a JSONObject, if it is a [, you are dealing with a JSONArray.
  2. If you are dealing with JSON (an Object), then you can do an instanceof check. yourObject instanceof JSONObject. This will return true if yourObject is a JSONObject. The same applies to JSONArray.

Solution 3 - Android

This is the simple solution I'm using on Android:

JSONObject json = new JSONObject(jsonString);

if (json.has("data")) {
	
	JSONObject dataObject = json.optJSONObject("data");

	if (dataObject != null) {

		//Do things with object.

	} else {

		JSONArray array = json.optJSONArray("data");

		//Do things with array
	}
} else {
    // Do nothing or throw exception if "data" is a mandatory field
}

Solution 4 - Android

Presenting an another way :

if(server_response.trim().charAt(0) == '[') {
    Log.e("Response is : " , "JSONArray");
} else if(server_response.trim().charAt(0) == '{') {
    Log.e("Response is : " , "JSONObject");
}

Here server_response is a response String coming from server

Solution 5 - Android

A more fundamental way of doing this is the following.

JsonArray is inherently a List

JsonObject is inherently a Map

if (object instanceof Map){
	JSONObject jsonObject = new JSONObject();
	jsonObject.putAll((Map)object);
    ...
    ...
}
else if (object instanceof List){
	JSONArray jsonArray = new JSONArray();
	jsonArray.addAll((List)object);
    ...
    ...
}

Solution 6 - Android

instanceof

Object.getClass().getName()

Solution 7 - Android

For those tackling this issue in JavaScript, the following did the job for me (not sure how efficient it is).

if(object.length != undefined) {
   console.log('Array found. Length is : ' + object.length); 
} else {
 console.log('Object found.'); 
}

Solution 8 - Android

JsonNode jsonNode=mapper.readTree(patchBody);

jsonNode has two method:
isObject();
isArray();

Solution 9 - Android

My approach would be a total abstraction from this. Maybe someone finds this useful...

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class SimpleJSONObject extends JSONObject {

	
	private static final String FIELDNAME_NAME_VALUE_PAIRS = "nameValuePairs";


	public SimpleJSONObject(String string) throws JSONException {
		super(string);
	}

	
	public SimpleJSONObject(JSONObject jsonObject) throws JSONException {
		super(jsonObject.toString());
	}

	
	@Override
	public JSONObject getJSONObject(String name) throws JSONException {
		
		final JSONObject jsonObject = super.getJSONObject(name);
		
		return new SimpleJSONObject(jsonObject.toString());
	}
	
	
	@Override
	public JSONArray getJSONArray(String name) throws JSONException {

		JSONArray jsonArray = null;
		
		try {
			
			final Map<String, Object> map = this.getKeyValueMap();
			
			final Object value = map.get(name);
			
			jsonArray = this.evaluateJSONArray(name, value);
	
		} catch (Exception e) {
			
			throw new RuntimeException(e);
			
		}
		
		return jsonArray;
	}


	private JSONArray evaluateJSONArray(String name, final Object value) throws JSONException {
		
		JSONArray jsonArray = null;
		
		if (value instanceof JSONArray) {
			
			jsonArray = this.castToJSONArray(value);
			
		} else if (value instanceof JSONObject) {
			
			jsonArray = this.createCollectionWithOneElement(value);
			
		} else {
			
			jsonArray = super.getJSONArray(name);
			
		}
		return jsonArray;
	}


	private JSONArray createCollectionWithOneElement(final Object value) {

		final Collection<Object> collection = new ArrayList<Object>();
		collection.add(value);
		
		return (JSONArray) new JSONArray(collection);
	}


	private JSONArray castToJSONArray(final Object value) {
		return (JSONArray) value;
	}


	private Map<String, Object> getKeyValueMap() throws NoSuchFieldException, IllegalAccessException {
		
		final Field declaredField = JSONObject.class.getDeclaredField(FIELDNAME_NAME_VALUE_PAIRS);
		declaredField.setAccessible(true);
		
		@SuppressWarnings("unchecked")
		final Map<String, Object> map = (Map<String, Object>) declaredField.get(this);
		
		return map;
	}
	

}

And now get rid of this behaviour forever...

...
JSONObject simpleJSONObject = new SimpleJSONObject(jsonObject);
...

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGregView Question on Stackoverflow
Solution 1 - AndroidneworldView Answer on Stackoverflow
Solution 2 - Androidnicholas.hauschildView Answer on Stackoverflow
Solution 3 - AndroidsourcerebelsView Answer on Stackoverflow
Solution 4 - AndroidBhargav ThankiView Answer on Stackoverflow
Solution 5 - AndroidPankaj SinghalView Answer on Stackoverflow
Solution 6 - AndroidHot LicksView Answer on Stackoverflow
Solution 7 - AndroidRafView Answer on Stackoverflow
Solution 8 - Androidfrank_liuView Answer on Stackoverflow
Solution 9 - AndroidoopexpertView Answer on Stackoverflow