JSON'un JSONObject mi yoksa JSONArray mi olduğunu belirleme


132

Sunucudan bir JSON Nesnesi veya Dizi alacağım, ancak hangisi olacağı hakkında hiçbir fikrim yok. JSON ile çalışmam gerekiyor, ancak bunu yapmak için bunun bir Nesne mi yoksa bir Dizi mi olduğunu bilmem gerekiyor.

Android ile çalışıyorum.

Bunu yapmanın iyi bir yolu olan var mı?


O yapmanın bir yolunu deserialing geldiğinde Android ile GSON kullanılıyorsa ve gibidir bu .
pirho

Yanıtlar:


244

Bunu belirlemenin daha iyi bir yolunu buldum:

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 daha fazla tür döndürebilir: http://developer.android.com/reference/org/json/JSONTokener.html#nextValue ()


1
iyi iş. umarım hem JsonObject hem de Json Array'i kontrol eder
Shreyash Mahajan

2
@neworld ama ya bir döngünün ortasındaysam. data.getJSONArray () veya data.getJSONObject () almaya çalışmak potansiyel olarak bir JSONEXception oluşturacaktır !!
P-RAD

Merhaba, nesne verilerim yanıtın ortasında, bu yüzden bunu nasıl tespit edebilirim? JSONObject veya JSONArray olup olmadığını kontrol etmek için ??? ve cevabınızda String data = "{...}"; tüm yanıtın değerine sahip mi ???
amit pandya

Bunu başarmak için JSON'unuzu kullanarak ayrıştırmanız gerekir JSONTokener. Bunu ben yapmadım, ama sanırım geçmelisiniz ("anahtarınız") . Ama emin değilim. Ancak, json eşleştiricisini kullanmayı düşünmelisiniz: Gson, Jackson, Moshi ve diğerleri.
neworld

53

Bunu yapmanın birkaç yolu vardır:

  1. Dize'nin ilk konumundaki karakteri kontrol edebilirsiniz (geçerli JSON'da izin verildiği için boşlukları kırptıktan sonra). Eğer bir a ise {, a ile JSONObject, eğer bir a ise, a [ile uğraşıyorsunuz JSONArray.
  2. JSON (an Object) ile uğraşıyorsanız , bir instanceofkontrol yapabilirsiniz . yourObject instanceof JSONObject. YourObject bir JSONObject ise bu true döndürür. Aynısı JSONArray için de geçerlidir.

3
Bu kesinlikle işe yaradı. Sonunda, dizeyi bir JSONObject'e koydum ve bir hata atarsa, bunun bir JSONArray olduğunu biliyordum. deneyin {yeni JSONObject (json) öğesini döndür; } catch (Exception e) {} try {return new JSONArray (json); } catch (İstisna e) {}
Greg

3
JSON verilerinin başında beyaz boşluklara izin verildiğinden, ilk seçeneğiniz güvenilir bir şekilde çalışmayacaktır. Baştaki herhangi bir beyaz boşluğu atlamanız ve ilk boşluk olmayan karakteri kontrol etmeniz gerekir.
user9876

1
@ user9876 Uyarılar için teşekkürler. Yorumunuzu yansıtacak şekilde düzenlendi.
nicholas.hauschild

14

Android'de kullandığım basit çözüm şudur:

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'e özgü değil ve bu sürümü en çok seviyorum çünkü karakter kontrolü kullanmıyor, ancak json.has("data")her şeyin isteğe bağlı olduğunu varsayıyor (istenmiyor).
Christophe Roussy

7

Başka bir yol sunmak:

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

İşte server_responsesunucudan gelen bir yanıt dizesi


1

Bunu yapmanın daha temel bir yolu şudur.

JsonArraydoğası gereği bir Listedir

JsonObjectdoğası gereği bir Haritadır

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

örneği

Object.getClass (). GetName ()


Sanırım soru düz bir dizeyle çalışacağınızı varsayıyor, bu nedenle instanceof veya getClass (). GetName () kullanmak işe yaramayacak.
gamerson

@gamerson - Bu garip - benim için birçok kez çalıştı. Ayrıştırıcının herhangi bir nesneyi döndürmesini sağlamanız gerekir, hangisini belirtmek yerine.
Hot Licks

1
Açıkçası insanlar bunu anlamıyor. Gördüğüm hemen hemen her ayrıştırıcının bir "JSONInstance" veya basitçe "Nesne" veya her neyse döndürme seçeneği vardır. JSON'u ayrıştırın ve ardından ne olduğunu sorun. Bu yeteneğe sahip olmayan bir ayrıştırıcı bozulmuştur.
Hot Licks

(Aslında bu Neworld'ün cevabı, aşağı yukarı.)
Hot Licks

0

JavaScript'te bu sorunu çözenler için, aşağıdaki işi benim için yaptı (ne kadar verimli olduğundan emin değilim).

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

-1

Benim yaklaşımım bundan tam bir soyutlama olacaktır. Belki birisi bunu yararlı bulur ...

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


}

Ve şimdi bu davranıştan sonsuza kadar kurtulun ...

...
JSONObject simpleJSONObject = new SimpleJSONObject(jsonObject);
...
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.