Визначте, чи JSON є JSONObject або JSONArray


132

Я збираюся отримувати або сервер JSON або масив від сервера, але я не маю уявлення, яким це буде. Мені потрібно працювати з JSON, але для цього мені потрібно знати, чи це Об'єкт чи масив.

Я працюю з Android.

Хтось має хороший спосіб зробити це?


При використанні Gson з Android , і коли справа доходить до deserialing один з способів зробити це, як це .
pirho

Відповіді:


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

Привіт мої об’єктні дані - це середина відповіді, то як я можу це виявити? перевірити, чи є його JSONObject чи JSONArray ??? і у вашій відповіді String data = "{...}"; має значення цілої відповіді ???
amit pandya

Для цього вам потрібно розібрати JSON за допомогою JSONTokener. Я цього не робив, але, мабуть, вам слід пропуститиPast ("your_key") . Але я не впевнений. Однак вам слід розглянути можливість використання картографа json: Gson, Jackson, Moshi та тонни інших.
neworld

53

Є кілька способів зробити це:

  1. Ви можете перевірити персонажа в першій позиції рядка (після обрізки пробілу, як це дозволено у дійсному JSON). Якщо це a {, ви маєте справу з a JSONObject, якщо це a [, ви маєте справу з a JSONArray.
  2. Якщо ви маєте справу з JSON (an Object), то можете зробити instanceofперевірку. yourObject instanceof JSONObject. Це повернеться істиною, якщо yourObject є JSONObject. Це ж стосується і JSONArray.

3
Це безумовно спрацювало. Зрештою, я поклав рядок у JSONObject, і якщо він видав помилку, то я знав, що це JSONArray. спробуйте {повернути новий JSONObject (json); } catch (Виняток е) {} спробуйте {повернути новий JSONArray (json); } лов (виняток е) {}
Грег,

3
Ваш перший варіант не працюватиме надійно, оскільки пробіл дозволений на початку даних JSON. Вам потрібно пропустити будь-який провідний пробіл і перевірити перший символ, який не є пробілом.
user9876

1
@ user9876 Дякую за голову. Відредаговано, щоб відобразити ваш коментар.
nicholas.hauschild

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")припустимо, вся справа не є обов'язковою (не вимагається).
Крістоф Руссі

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

instanceof

Object.getClass (). GetName ()


Я думаю, що питання передбачає, що ви будете працювати з простою рядком, тому використовуючи instanceof або getClass (). GetName () не буде працювати.
gamerson

@gamerson - Це дивно - він працював для мене багато разів. Вам просто потрібно, щоб парсер повернув будь-який об'єкт, проти зазначення якого.
Гарячі лизи

1
Очевидно, люди цього не розуміють. Практично кожен парсер, який я бачив, має можливість аналізу, щоб повернути "JSONInstance" або просто "Object", або що завгодно. Розберіть JSON, а потім запитайте, що це таке. Розбирається аналізатор, який не має цієї здатності.
Гарячі лизання

(Це, власне, відповідь 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);
...
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.