พิจารณาว่า JSON เป็น JSONObject หรือ JSONArray


135

ฉันจะได้รับ JSON Object หรือ Array จากเซิร์ฟเวอร์ แต่ฉันไม่รู้ว่าจะเป็นอย่างไร ฉันต้องทำงานกับ JSON แต่ในการทำเช่นนั้นฉันต้องรู้ว่ามันเป็น Object หรือ Array

ฉันกำลังทำงานกับ Android

ใครมีวิธีที่ดีในการทำเช่นนี้หรือไม่?


ถ้าใช้ Gson กับ Android และเมื่อมันมาถึง deserialing วิธีหนึ่งที่จะทำมันเป็นเหมือน นี้
pirho

คำตอบ:


249

ฉันพบวิธีที่ดีกว่าในการพิจารณา:

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

สวัสดี objectdata ของฉันอยู่ตรงกลางของการตอบสนองดังนั้นฉันจะตรวจพบได้อย่างไร เพื่อตรวจสอบว่าเป็น JSONObject หรือ JSONArray ??? และในคำตอบของคุณ String data = "{... }"; มีคุณค่าของการตอบสนองทั้งหมด ???
amit pandya

หากต้องการประสบความสำเร็จที่คุณต้องแยก JSON JSONTokenerของคุณโดยใช้ ผมไม่ได้ทำอย่างนั้น แต่ฉันคิดว่าคุณควรskipPast ( "your_key") แต่ผมไม่แน่ใจ อย่างไรก็ตามคุณควรพิจารณาใช้ json mapper: Gson, Jackson, Moshi และอื่น ๆ อีกมากมาย
neworld

54

มีสองวิธีที่คุณสามารถทำได้:

  1. คุณสามารถตรวจสอบอักขระที่ตำแหน่งแรกของ String (หลังจากตัดช่องว่างออกไปเนื่องจากอนุญาตให้ใช้ใน JSON ที่ถูกต้อง) ถ้าเป็น{คุณกำลังติดต่อกับ a JSONObjectถ้าเป็น[คุณกำลังติดต่อกับไฟล์JSONArray.
  2. หากคุณกำลังจัดการกับ JSON (an Object) คุณสามารถinstanceofตรวจสอบได้ yourObject instanceof JSONObject. สิ่งนี้จะส่งคืนจริงหาก yourObject เป็น JSONObject เช่นเดียวกับ JSONArray

3
ที่ได้ผลแน่นอน ในท้ายที่สุดฉันใส่สตริงลงใน JSONObject และถ้ามันเกิดข้อผิดพลาดฉันก็รู้ว่ามันเป็น JSONArray ลอง {ส่งคืน JSONObject ใหม่ (json); } catch (ข้อยกเว้นจ) {} ลอง {return new JSONArray (json); } catch (ข้อยกเว้นจ) {}
Greg

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")สมมติว่าทุกอย่างเป็นทางเลือก (ไม่ได้ขอ)
Christophe Roussy

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

อินสแตนซ์ของ

Object.getClass (). getName ()


ฉันคิดว่าคำถามสันนิษฐานว่าคุณจะทำงานกับสตริงธรรมดาดังนั้นการใช้ instanceof หรือ getClass () getName () จะไม่ทำงาน
gamerson

@gamerson - มันแปลก - มันใช้ได้กับฉันหลายครั้ง คุณเพียงแค่ต้องให้ parser ส่งคืนอ็อบเจ็กต์อย่างใดอย่างหนึ่งเทียบกับการระบุซึ่ง
Hot Licks

1
เห็นได้ชัดว่าผู้คนไม่เข้าใจสิ่งนี้ ตัวแยกวิเคราะห์ทุกตัวที่ฉันเคยเห็นมีตัวเลือกในการแยกวิเคราะห์เพื่อส่งคืน "JSONInstance" หรือ "Object" หรืออะไรก็ตาม แยกวิเคราะห์ JSON แล้วถามว่ามันคืออะไร โปรแกรมแยกวิเคราะห์ที่ไม่มีความสามารถนี้ใช้งานไม่ได้
Hot Licks

(นี่คือคำตอบของ 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);
...
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.