JSON이 JSONObject인지 JSONArray인지 확인


132

서버에서 JSON 객체 또는 배열을 수신하려고하지만 그것이 무엇인지 알 수 없습니다. JSON으로 작업해야하지만 그렇게하려면 Object인지 Array인지 알아야합니다.

Android로 작업하고 있습니다.

아무도 이것을하는 좋은 방법이 있습니까?


Android에서 Gson을 사용하는 경우 한 가지 방법으로 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 배열 모두에 대해 확인 바랍니다
Shreyash 마하 잔

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

53

이를 수행 할 수있는 몇 가지 방법이 있습니다.

  1. 유효한 JSON에서 허용되므로 공백을 자른 후 문자열의 첫 번째 위치에서 문자를 확인할 수 있습니다. 그것이이면을 {처리하고 있고 JSONObject이면을 [처리하고있는 것 JSONArray입니다.
  2. JSON ( Object)을 다루는 경우 instanceof검사를 수행 할 수 있습니다 . yourObject instanceof JSONObject. yourObject가 JSONObject 인 경우 true를 반환합니다. JSONArray에도 동일하게 적용됩니다.

3
확실히 효과가있었습니다. 결국에는 문자열을 JSONObject에 넣고 오류가 발생하면 JSONArray라는 것을 알았습니다. {return new JSONObject (json);을 시도하십시오 } catch (예외 e) {} try {return new JSONArray (json); } catch (예외 e) {}
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
안드로이드 전용이 아니며 문자 검사를 사용하지 않기 때문에이 버전이 가장 좋습니다.하지만 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-이상합니다-여러 번 일했습니다. 파서는 두 객체 중 하나를 지정하여 객체를 반환해야합니다.
핫 릭

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.