确定JSON是JSONObject还是JSONArray


132

我将从服务器接收JSON对象或数组,但是我不知道它将是什么。我需要使用JSON,但是要这样做,我需要知道它是对象还是数组。

我正在使用Android。

有没有人有这样做的好方法?


如果使用GSON Android和当谈到deserialing一个办法做到这一点就像 这样
pirho

Answers:


244

我找到了更好的方法来确定:

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可以返回更多类型:http : //developer.android.com/reference/org/json/JSONTokener.html#nextValue()


1
不错的工作。希望它将检查JsonObject和Json Array
Shreyash Mahajan

2
@neworld,但是如果我处于循环中间怎么办。尝试获取data.getJSONArray()或data.getJSONObject()可能会引发JSONEXception!
P-RAD

嗨,我的objectdata是响应的中间,所以我怎么能检测到呢?检查它是JSONObject还是JSONArray ???并且在您的答案中String data =“ {...}”; 具有整体回应的价值???
阿米·潘迪亚(Amit Pandya)'17

为此,您必须使用解析JSON JSONTokener。我没有这样做,但是我想您应该skipPast(“ your_key”)。但是我不确定。但是,您应该考虑使用json映射器:Gson,Jackson,Moshi和其他许多人。
neworld

53

有两种方法可以执行此操作:

  1. 您可以在String的第一个位置检查字符(修剪掉空格后,因为有效JSON允许使用该字符)。如果是a {,则表示正在处理a JSONObject,如果是a [,则表示正在处理JSONArray
  2. 如果您正在处理JSON(一个Object),则可以进行instanceof检查。 yourObject instanceof JSONObject。如果yourObject是JSONObject,则返回true。JSONArray也是如此。

3
那绝对有效。最后,我将字符串放入JSONObject中,如果抛出错误,那么我知道它是JSONArray。尝试{返回新的JSONObject(json); } catch(Exception e){} try {返回新的JSONArray(json); } catch(Exception e){}
Greg

3
您的第一个选项无法可靠运行,因为在JSON数据的开头允许使用空格。您需要跳过任何前导空格,并检查第一个非空格字符。
user9876 2014年

1
@ user9876感谢您的注意。编辑以反映您的评论。
nicholas.hauschild 2014年

14

这是我在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
}

1
不是Android专用的,我最喜欢这个版本,因为它不使用任何字符检查,但是json.has("data")假设整个过程都是可选的(不需要)。
Christophe Roussy

7

提出另一种方式:

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

server_response是来自服务器的响应字符串


1

下面是一个更基本的方法。

JsonArray本质上是一个列表

JsonObject本质上是地图

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

0

实例

Object.getClass()。getName()


我认为这个问题假设您将使用纯字符串,因此使用instanceof或getClass()。getName()无效。
玩家

@gamerson-很奇怪-它为我工作了很多次。您只需要让解析器返回任一对象,而不是指定哪个对象即可。
热门点击2012年

1
显然,人们不理解这一点。我见过的几乎每个解析器都有一个解析选项,可以返回“ JSONInstance”或“ Object”或其他任何内容。解析JSON,然后询问它是什么。没有此功能的解析器已损坏。
Hot Licks 2014年

(事实上​​,这差不多是Neworld的答案。)
Hot Licks

0

对于那些用JavaScript解决此问题的人,以下对我有用(不确定它的效率)。

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

-1

我的方法是从中完全抽象出来。也许有人觉得这很有用...

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


}

现在永远摆脱这种行为...

...
JSONObject simpleJSONObject = new SimpleJSONObject(jsonObject);
...
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.