Tentukan apakah JSON adalah JSONObject atau JSONArray

132

Saya akan menerima JSON Object atau Array dari server, tetapi saya tidak tahu akan seperti apa. Saya perlu bekerja dengan JSON, tetapi untuk melakukannya, saya perlu tahu apakah itu Obyek atau Array.

Saya bekerja dengan Android.

Apakah ada yang punya cara bagus untuk melakukan ini?

Greg
sumber
Jika menggunakan Gson dengan Android dan ketika melakukan deserialing, salah satu cara untuk melakukannya adalah seperti ini .
pirho

Jawaban:

244

Saya menemukan cara yang lebih baik untuk menentukan:

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 dapat mengembalikan lebih banyak jenis: http://developer.android.com/reference/org/json/JSONTokener.html#nextValue ()

dunia baru
sumber
1
pekerjaan yang baik. berharap itu akan memeriksa JsonObject dan Json Array
Shreyash Mahajan
2
@neworld tetapi bagaimana jika saya berada di tengah-tengah lingkaran. mencoba untuk mendapatkan data.getJSONArray () atau data.getJSONObject () berpotensi membuang JSONEXception !!
P-RAD
Hai objectdata saya berada di tengah-tengah respon jadi bagaimana saya bisa mendeteksi itu? untuk memeriksa apakah ini JSONObject atau JSONArray ??? dan Dalam jawaban Anda Data string = "{...}"; apakah memiliki nilai seluruh respons ???
amit pandya
Untuk mencapai itu, Anda harus mengurai JSON menggunakan JSONTokener. Saya tidak melakukan itu, tapi saya kira Anda harus melewatkan Last ("your_key") . Tapi saya tidak yakin. Namun, Anda harus mempertimbangkan untuk menggunakan json mapper: Gson, Jackson, Moshi dan banyak lainnya.
neworld
53

Ada beberapa cara Anda bisa melakukan ini:

  1. Anda dapat memeriksa karakter di posisi pertama String (setelah memangkas spasi kosong, karena diizinkan dalam JSON yang valid). Jika itu adalah {, Anda berurusan dengan JSONObject, jika itu adalah [, Anda berhadapan dengan a JSONArray.
  2. Jika Anda berurusan dengan JSON (an Object), maka Anda dapat melakukan instanceofpemeriksaan. yourObject instanceof JSONObject. Ini akan mengembalikan true jika objek Anda adalah objek JSON. Hal yang sama berlaku untuk JSONArray.
nicholas.hauschild
sumber
3
Itu pasti berhasil. Pada akhirnya, saya memasukkan string ke dalam JSONObject dan jika itu membuat kesalahan, maka saya tahu itu adalah JSONArray. coba {return new JSONObject (json); } catch (Exception e) {} coba {return JSONArray baru (json); } catch (Exception e) {}
Greg
3
Opsi pertama Anda tidak akan bekerja dengan andal, karena spasi putih diizinkan pada awal data JSON. Anda perlu melewati spasi spasi apa pun yang terkemuka dan memeriksa karakter non-spasi pertama.
user9876
1
@ user9876 Terima kasih atas bantuannya. Diedit untuk mencerminkan komentar Anda.
nicholas.hauschild
14

Ini adalah solusi sederhana yang saya gunakan di 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
}
sourcerebels
sumber
1
Bukan Android spesifik dan saya paling suka versi ini karena tidak menggunakan pemeriksaan karakter, tetapi json.has("data")seandainya semuanya opsional (tidak diminta).
Christophe Roussy
7

Menghadirkan cara lain:

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

Berikut server_responseini respons String yang berasal dari server

Bhargav Thanki
sumber
1

Cara yang lebih mendasar untuk melakukan ini adalah sebagai berikut.

JsonArraysecara inheren Daftar

JsonObjectpada dasarnya adalah Peta

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);
    ...
    ...
}
Pankaj Singhal
sumber
0

contoh

Object.getClass (). GetName ()

Hot Licks
sumber
Saya pikir pertanyaannya mengasumsikan bahwa Anda akan bekerja dengan string polos sehingga menggunakan instanceof atau getClass (). GetName () tidak akan berfungsi.
gamerson
@ Giberson - Aneh - ini bekerja untuk saya berkali-kali. Anda hanya perlu memiliki parser mengembalikan objek, vs menentukan yang.
Hot Licks
1
Jelas orang tidak mengerti ini. Hampir setiap parser yang saya lihat memiliki opsi parse untuk mengembalikan "JSONInstance" atau cukup "Object", atau apa pun. Parsing JSON dan tanyakan apa itu. Pengurai yang tidak memiliki kemampuan ini rusak.
Hot Licks
(Ini, pada kenyataannya, jawaban Neworld, kurang lebih.)
Hot Licks
0

Bagi mereka yang menangani masalah ini dalam JavaScript, berikut ini melakukan pekerjaan untuk saya (tidak yakin seberapa efisien itu).

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

Pendekatan saya akan menjadi abstraksi total dari ini. Mungkin seseorang menemukan ini berguna ...

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


}

Dan sekarang singkirkan perilaku ini selamanya ...

...
JSONObject simpleJSONObject = new SimpleJSONObject(jsonObject);
...
oopexpert
sumber