Determinare se JSON è un JSONObject o JSONArray


132

Riceverò un oggetto JSON o un array dal server, ma non ho idea di quale sarà. Devo lavorare con JSON, ma per farlo, devo sapere se si tratta di un oggetto o una matrice.

Sto lavorando con Android.

Qualcuno ha un buon modo per farlo?


Se si utilizza GSON con Android e quando si tratta di deserialing un modo per farlo è come questo .
pirho,

Risposte:


244

Ho trovato il modo migliore per determinare:

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 è in grado di restituire più tipi: http://developer.android.com/reference/org/json/JSONTokener.html#nextValue ()


1
bel lavoro. spero che controllerà sia JsonObject che Json Array
Shreyash Mahajan,

2
@neworld ma cosa succede se sono nel mezzo di un ciclo. il tentativo di ottenere un data.getJSONArray () o data.getJSONObject () genererà potenzialmente una JSONEXception !!
P-RAD,

Ciao i miei objectdata sono al centro della risposta, quindi come posso rilevarlo? controllare se si tratta di un JSONObject o JSONArray ??? e nella tua risposta String data = "{...}"; sta avendo valore dell'intera risposta ???
amand pandya,

Per fare ciò, devi analizzare il tuo JSON usando JSONTokener. Non l'ho fatto, ma suppongo che dovresti saltare Skip ("tuo_chiave") . Ma non sono sicuro. Tuttavia, dovresti considerare l'utilizzo di json mapper: Gson, Jackson, Moshi e molti altri.
Neworld,

53

Ci sono un paio di modi per farlo:

  1. È possibile controllare il carattere nella prima posizione della stringa (dopo aver eliminato gli spazi bianchi, poiché è consentito in JSON valido). Se è a {, hai a che fare con a JSONObject, se è a [, hai a che fare con a JSONArray.
  2. Se hai a che fare con JSON (an Object), puoi fare un instanceofcontrollo. yourObject instanceof JSONObject. Ciò restituirà true se yourObject è un JSONObject. Lo stesso vale per JSONArray.

3
Questo ha sicuramente funzionato. Alla fine però, ho inserito la stringa in un oggetto JSONObject e se ha generato un errore, ho capito che si trattava di un JSONArray. provare {return new JSONObject (json); } catch (Exception e) {} try {return new JSONArray (json); } catch (Exception e) {}
Greg,

3
La tua prima opzione non funzionerà in modo affidabile, perché gli spazi bianchi sono consentiti all'inizio dei dati JSON. Devi saltare qualsiasi spazio bianco iniziale e controllare il primo carattere non bianco.
user9876

1
@ user9876 Grazie per l'heads up. Modificato per riflettere il tuo commento.
nicholas.hauschild,

14

Questa è la soluzione semplice che sto usando su 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
Non specifico per Android e questa versione mi piace di più perché non utilizza controlli dei caratteri, ma json.has("data")supponiamo che il tutto sia facoltativo (non richiesto).
Christophe Roussy,

7

Presentando un altro modo:

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

Ecco server_responseuna stringa di risposta proveniente dal server


1

Un modo più fondamentale per farlo è il seguente.

JsonArrayè intrinsecamente un elenco

JsonObjectè intrinsecamente una Mappa

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


Penso che la domanda presuma che lavorerai con una stringa semplice, quindi usando l'istanza o getClass (). GetName () non funzionerà.
gamerson

@gamerson - Strano - ha funzionato per me molte volte. Devi solo fare in modo che il parser restituisca uno o più oggetti, specificando quale.
Hot Licks

1
Chiaramente la gente non lo capisce. Praticamente ogni parser che ho visto ha un'opzione di analisi per restituire un "JSONInstance" o semplicemente "Object", o qualsiasi altra cosa. Analizza il JSON e poi chiedigli di cosa si tratta. Un parser che non ha questa capacità è rotto.
Hot Licks

(Questa è, in effetti, la risposta di Neworld, più o meno.)
Hot Licks

0

Per coloro che affrontano questo problema in JavaScript, il seguente ha fatto il lavoro per me (non sono sicuro di quanto sia efficiente).

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

-1

Il mio approccio sarebbe un'astrazione totale da questo. Forse qualcuno lo trova utile ...

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


}

E ora sbarazzati di questo comportamento per sempre ...

...
JSONObject simpleJSONObject = new SimpleJSONObject(jsonObject);
...
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.