【问题标题】:Determine whether JSON is a JSONObject or JSONArray确定 JSON 是 JSONObject 还是 JSONArray
【发布时间】:2011-09-01 09:36:59
【问题描述】:

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

我正在使用 Android。

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

【问题讨论】:

  • 如果将 Gson 与 Android 一起使用,并且当涉及到反序列化一种方法时,就像 this

标签: android arrays json object


【解决方案1】:

实例

Object.getClass().getName()

【讨论】:

  • 我认为问题假设您将使用纯字符串,因此使用 instanceof 或 getClass().getName() 将不起作用。
  • @gamerson -- 这很奇怪 -- 它对我有用很多次。您只需要让解析器返回任一对象,而不是指定哪个。
  • 显然人们不明白这一点。我见过的几乎每个解析器都有一个解析选项来返回一个“JSONInstance”或简单的“Object”,或者其他什么。解析 JSON,然后询问它是什么。不具备此功能的解析器已损坏。
  • (实际上,这或多或少是 Neworld 的答案。)
【解决方案2】:

有几种方法可以做到这一点:

  1. 您可以检查字符串第一个位置的字符(在修剪掉空格之后,因为它在有效的 JSON 中是允许的)。如果是{,你正在处理JSONObject,如果是[,你正在处理JSONArray
  2. 如果您正在处理 JSON(Object),那么您可以进行instanceof 检查。 yourObject instanceof JSONObject。如果 yourObject 是 JSONObject,这将返回 true。这同样适用于 JSONArray。

【讨论】:

  • 这绝对有效。最后,我将字符串放入一个 JSONObject 中,如果它抛出错误,那么我知道它是一个 JSONArray。尝试 { 返回新的 JSONObject(json); } catch (Exception e) { } try { return new JSONArray(json); } 捕捉(异常 e){ }
  • 您的第一个选项不会可靠地工作,因为在 JSON 数据的开头允许使用空格。您需要跳过任何前导空格并检查第一个非空格字符。
  • @user9876 感谢您的提醒。已编辑以反映您的评论。
【解决方案3】:

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

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()

【讨论】:

  • 干得好。希望它会检查 JsonObject 和 Json Array
  • @neworld 但是如果我处于循环中怎么办。尝试获取 data.getJSONArray() 或 data.getJSONObject() 可能会引发 JSONEXception!
  • 嗨,我的 objectdata 是响应的中间,所以我怎么能检测到呢?检查它是 JSONObject 还是 JSONArray ???并在您的答案中 String data = "{ ... }";是否具有整个响应的价值???
  • 为此,您必须使用 JSONTokener 解析您的 JSON。我没有这样做,但我想你应该skipPast("your_key")。但我不确定。但是,您应该考虑使用 json 映射器:Gson、Jackson、Moshi 和其他许多人。
【解决方案4】:

我的方法是对此进行完全抽象。也许有人觉得这很有用...

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

【讨论】:

    【解决方案5】:

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

    【讨论】:

    • 不是 Android 特定的,我最喜欢这个版本,因为它不使用字符检查,但 json.has("data") 假设整个事情是可选的(不要求)。
    【解决方案6】:

    对于那些在 JavaScript 中解决此问题的人,以下为我完成了这项工作(不确定它的效率如何)。

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

    【讨论】:

      【解决方案7】:

      执行此操作的更基本方法如下。

      JsonArray 本质上是List

      JsonObject 本质上是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);
          ...
          ...
      }
      

      【讨论】:

        【解决方案8】:

        另一种方式:

        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是来自服务器的响应字符串

        【讨论】:

          【解决方案9】:
          JsonNode jsonNode=mapper.readTree(patchBody);
          

          jsonNode 有两种方法:
          isObject();
          isArray();

          【讨论】:

            猜你喜欢
            • 2017-10-13
            • 2012-04-16
            • 1970-01-01
            • 2011-11-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多