developer tip

JSON jsonObject.optString ()은 문자열 "null"을 반환합니다.

optionbox 2021. 1. 11. 08:03
반응형

JSON jsonObject.optString ()은 문자열 "null"을 반환합니다.


서버 통신에 JSON을 사용하는 Android 앱을 개발 중이며 json 파일을 구문 분석하려고 할 때 이상한 문제가 있습니다.

이것은 서버의 json입니다.

{
    "street2": null,
    "province": null,
    "street1": null,
    "postalCode": null,
    "country": null,
    "city": null
}

String city = address.optString("city", "")내 주소 Json-object를 호출 하여 City의 가치를 얻고 있습니다. 이 상황 city에서는 비어 있을 것으로 예상 하고 있지만 (이것이 optString이 여기에있는 이유가 아닌가요?) 실제로는 String "null"을 포함합니다. 따라서 추가 null 또는 isEmpty 검사는 문자열에 텍스트가 포함되어 있으므로 false를 반환합니다. 내가 전화 address.isNull("city")하면 올바른 사실을 반환합니다. optString실패합니다.

이 문제에 대해 Google 또는 Stackoverflow에서 아무것도 찾을 수 없습니다. 나는 optString내가 예상 한대로 정확히 할 것이라고 생각했던 것처럼 그것이 어떻게 일어날 수 있는지 정말로 이해하지 못한다 . 여기에서 무엇이 잘못되었는지 아는 사람 있나요?


이 문제에 부딪 히고 머리를 긁적 거리며 "그들이 정말로 이것을 의미했을까요?"라고 생각하는 것은 혼자가 아닙니다. AOSP 문제에 따르면 Google 엔지니어 이를 버그로 간주 했지만 org.json 구현과 호환되어야하고 버그와도 호환되어야했습니다.

생각해 보면, 같은 라이브러리를 사용하는 동일한 코드가 다른 Java 환경에서 실행되는 동일한 코드가 Android에서 다르게 작동하면 타사 라이브러리를 사용할 때 주요 호환성 문제가 발생하기 때문에 의미가 있습니다. 의도가 좋고 진정으로 버그를 수정하더라도 완전히 새로운 웜 캔을 열 수 있습니다.

AOSP 문제 에 따르면 :

의도적 인 행동입니다. 우리는 org.json과 버그 호환이되기 위해 나섰습니다. 이제 수정되었으므로 코드도 수정해야하는지 여부가 명확하지 않습니다. 응용 프로그램이이 버그 동작에 의존하게되었을 수 있습니다.

이것이 슬픔을 유발하는 경우 json.isNull ()과 같은 다른 메커니즘을 사용하여 null을 테스트하여 해결 방법을 권장합니다.

여기에 도움이되는 간단한 방법이 있습니다.

/** Return the value mapped by the given key, or {@code null} if not present or null. */
public static String optString(JSONObject json, String key)
{
    // http://code.google.com/p/android/issues/detail?id=13830
    if (json.isNull(key))
        return null;
    else
        return json.optString(key, null);
}

기본적으로 두 가지 선택이 있습니다.

1) null 값으로 JSON 페이로드 보내기

{
"street2": "s2",
"province": "p1",
"street1": null,
"postalCode": null,
"country": null,
"city": null
}

null 값을 확인하고 그에 따라 구문 분석해야합니다.

private String optString_1(final JSONObject json, final String key) {
    return json.isNull(key) ? null : json.optString(key);
}

2) null 값이있는 키를 보내지 말고 optString (key, null)을 직접 사용하십시오 (대역폭을 절약해야 함).

{
"street2": "s2",
"province": "p1"
}

당함 간단하게 대체하여이 문제를 없애 "null"와 함께 "".

String city = address.optString("city").replace("null", "");

if (json != null && json.getString(KEY_SUCCESS) != null){
     // PARSE RESULT 
}else{
    // SHOW NOTIFICIATION: URL/SERVER NOT REACHABLE

}

그것은 키워드로 json null을 확인하는 것입니다.

JSONObject json = new JSONObject("{\"hello\":null}");
json.getString("hello");

이것은 null이 아닌 String "null"입니다.

너의 소리 사용

if(json.isNull("hello")) {
    helloStr = null;
} else {
    helloStr = json.getString("hello");
}

먼저 isNull ()로 확인하십시오 .... 작동하지 않으면 아래를 시도하십시오.

또한 null 값을 확인하는 JSONObject.NULL이 있습니다.

 if ((resultObject.has("username")
    && null != resultObject.getString("username")
    && resultObject.getString("username").trim().length() != 0)
    {
           //not null
    }

그리고 귀하의 경우에는

resultObject.getString("username").trim().eqauls("null")

먼저 json을 구문 분석하고 나중에 객체를 처리해야하는 경우 시도해보십시오.

파서

Object data = json.get("username");

매니저

 if (data instanceof Integer || data instanceof Double || data instanceof Long) {
        // handle number ;
  } else if (data instanceof String) {
        // hanle string;               
  } else if (data == JSONObject.NULL) {
        // hanle null;                 
  }

Matt Quigley의 답변을 기반으로 Kotlin 및 Java로 작성된 폴백 부분을 포함하여 optString의 전체 기능을 모방하려는 경우 코드가 있습니다.

Kotlin :

fun optString(json: JSONObject, key: String, fallback: String?): String? {
    var stringToReturn = fallback
    if (!json.isNull(key)) {
        stringToReturn = json.optString(key, null)
    }
    return stringToReturn
}

자바:

public static String optString(JSONObject json, String key, String fallback) {
    String stringToReturn = fallback;
    if (!json.isNull(key)) {
        stringToReturn = json.optString(key, null);
    }
    return stringToReturn;
 }

fallback이 필요하지 않은 경우 fallback 매개 변수에 null을 전달하면됩니다.


내 Josn 파서는 길고이를 수정하기 위해 새 클래스를 만들어야했습니다. 그런 다음 각 메서드에 한 줄을 추가하고 현재 JSONObject 속성 이름의 이름을 변경해야했기 때문에 다른 모든 호출은 JSONObject 대신 새 클래스를 참조했습니다.

    public static ArrayList<PieceOfNews> readNews(String json) {
    if (json != null) {
        ArrayList<PieceOfNews> res = new ArrayList<>();
        try {
            JSONArray jsonArray = new JSONArray(json);
            for (int i = 0; i < jsonArray.length(); i++) {
                //before JSONObject jo = jsonArray.getJSONObject(i);
                JSONObject joClassic = jsonArray.getJSONObject(i);
                //facade
                FixJsonObject jo = new FixJsonObject(joClassic);
                PieceOfNews pn = new PieceOfNews();
                pn.setId(jo.getInt("id"));
                pn.setImageUrl(jo.getString("imageURL"));
                pn.setText(jo.getString("text"));
                pn.setTitle(jo.getString("title"));
                pn.setDate(jo.getLong("mills"));
                res.add(pn);
            }
            return res;
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
    return null;
}

여기에 내가 필요한 메소드가있는 수업이 있습니다. 더 추가 할 수 있습니다.

public class FixJsonObject {
private JSONObject jsonObject;

public FixJsonObject(JSONObject jsonObject) {
    this.jsonObject = jsonObject;
}

public String optString(String key, String defaultValue) {
    if (jsonObject.isNull(key)) {
        return null;
    } else {
        return jsonObject.optString(key, defaultValue);
    }
}

public String optString(String key) {
    return optString(key, null);
}

public int optInt(String key) {
    if (jsonObject.isNull(key)) {
        return 0;
    } else {
        return jsonObject.optInt(key, 0);
    }
}

public double optDouble(String key) {
    return optDouble(key, 0);
}

public double optDouble(String key, double defaultValue) {
    if (jsonObject.isNull(key)) {
        return 0;
    } else {
        return jsonObject.optDouble(key, defaultValue);
    }
}

public boolean optBoolean(String key, boolean defaultValue) {
    if (jsonObject.isNull(key)) {
        return false;
    } else {
        return jsonObject.optBoolean(key, defaultValue);
    }
}

public long optLong(String key) {
    if (jsonObject.isNull(key)) {
        return 0;
    } else {
        return jsonObject.optLong(key, 0);
    }
}

public long getLong(String key) {
    return optLong(key);
}

public String getString(String key) {
    return optString(key);
}

public int getInt(String key) {
    return optInt(key);
}

public double getDouble(String key) {
    return optDouble(key);
}

public JSONArray getJSONArray(String key) {
    if (jsonObject.isNull(key)) {
        return null;
    } else {
        return jsonObject.optJSONArray(key);
    }
}

}


아래와 같이 key 값이 null 인 경우

{

  "status": 200,

  "message": "",

  "data": {

    "totalFare": null,
  },

}

check with "isNull" , for Eg:

String strTotalFare;

if (objResponse.isNull("totalFare")) 

{

  strTotalFare = "0";

} else {

 strTotalFare = objResponse.getString("totalFare");

}

"totalFare"키에 대해 값이 "null"이면 위의 함수는 if를 입력하고 값을 0으로 할당합니다. 그렇지 않으면 키에서 실제 값을 가져옵니다.

참조 URL : https://stackoverflow.com/questions/18226288/json-jsonobject-optstring-returns-string-null

반응형