web-dev-qa-db-ger.com

JSON jsonObject.optString () gibt den String "null" zurück

Ich entwickle eine Android-App, die JSON für die Serverkommunikation verwendet, und ich habe ein komisches Problem, wenn ich versuche, meine Json-Datei zu analysieren.

Dies ist mein Json vom Server

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

Ich erhalte den Wert für City, indem ich String city = address.optString("city", "") für meine Adresse Json-object anrufe. Für diese Situation erwarte ich, dass city leer ist (dafür ist optString da, oder?), Aber tatsächlich enthält es den String "null". Weitere Null- oder isEmpty-Prüfungen geben also false zurück, da der String Text enthält. Wenn ich address.isNull("city") anrufe, wird true zurückgegeben, was korrekt ist. Nur optString schlägt fehl.

Ich konnte bei Google oder Stackoverflow für dieses Problem nichts finden. Ich verstehe nicht wirklich, wie das passieren kann, da ich dachte, optString würde genau das tun, was ich erwartet hatte. Weiß jemand, was hier schief läuft?

49
joschplusa

Sie sind nicht alleine, wenn Sie auf dieses Problem stoßen und sich den Kopf kratzen, wenn Sie denken: "Haben sie das wirklich gemeint?" Laut einem AOSP-Problem haben die Google-Ingenieure didbetrachten Sie dies als Fehler, aber sie mussten mit der org.json-Implementierung kompatibel sein, sogar mit Fehlern. 

Wenn Sie darüber nachdenken, ist es sinnvoll, denn wenn derselbe Code, der dieselben Bibliotheken verwendet, die in anderen Java-Umgebungen ausgeführt werden, sich in Android anders verhält, gibt es bei der Verwendung von Drittanbieter-Bibliotheken größere Kompatibilitätsprobleme. Selbst wenn die Absichten gut waren und Fehler wirklich behoben wurden, würde dies eine völlig neue Dose Würmer öffnen.

Laut der AOSP-Ausgabe :

Das Verhalten ist beabsichtigt; Wir haben alles getan, um mit org.json kompatibel zu sein. Nun, da dies behoben ist, ist es unklar, ob wir auch unseren Code korrigieren sollten. Anwendungen verlassen sich möglicherweise auf dieses fehlerhafte Verhalten.

Wenn dies zu Trauer führt, empfehle ich Ihnen eine Problemumgehung, indem Sie einen anderen Mechanismus zum Testen auf null verwenden, beispielsweise json.isNull ().

Hier ist eine einfache Methode, um Ihnen zu helfen:

/** 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);
}
81
Matt Quigley

Sie haben grundsätzlich 2 Möglichkeiten:

1) Senden Sie eine JSON-Nutzlast mit Nullwerten

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

Sie müssen nach Nullwerten suchen und diese entsprechend analysieren:

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

2) Senden Sie die Schlüssel nicht mit Nullwerten und verwenden Sie optString (Schlüssel, Null) direkt.

{
"street2": "s2",
"province": "p1"
}
23
dev.serghini
if (json != null && json.getString(KEY_SUCCESS) != null){
     // PARSE RESULT 
}else{
    // SHOW NOTIFICIATION: URL/SERVER NOT REACHABLE

}

das ist für die Überprüfung von Json Null mit dem Schlüsselwort.

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

dies ist der String "null" und nicht null.

ihre Shoud verwenden

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

zuerst mit isNull () überprüfen .... wenn nicht funktionieren kann, dann versuche es mit belows

und außerdem haben Sie JSONObject.NULL, um den Nullwert zu überprüfen ...

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

und in deinem Fall auch überprüfen 

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

Wenn Sie json zuerst analysieren und Objekte später bearbeiten müssen, lassen Sie es versuchen

Parser

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

Handler

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

Beseitigen Sie diese Situation, indem Sie einfach "null" durch "" ersetzen.

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

Mein Josn-Parser war lang und musste eine neue Klasse erstellen, um das Problem zu beheben. Dann musste nur eine zusätzliche Zeile in jede Methode eingefügt und der aktuelle JSONObject-Eigenschaftenname umbenannt werden, sodass alle anderen Aufrufe auf meine neue Klasse statt auf JSONObject verweisen . 

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

Hier ist meine Klasse mit den Methoden, die ich brauchte, Sie können weitere hinzufügen

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

}

0
Galeen

Wenn die Werte für den Schlüssel null sind, siehe unten 

{

  "status": 200,

  "message": "",

  "data": {

    "totalFare": null,
  },

}

check with "isNull" , for Eg:

String strTotalFare;

if (objResponse.isNull("totalFare")) 

{

  strTotalFare = "0";

} else {

 strTotalFare = objResponse.getString("totalFare");

}

wenn der Wert "null" für den Schlüssel "totalFare" ist, gibt die obige Funktion ein, ob und geben den Wert Null an.

0

Wenn Sie die Antwort von Matt Quigley als Basis verwenden, finden Sie hier den Code, wenn Sie die volle Funktionalität von optString nachahmen möchten, einschließlich des in Kotlin und Java geschriebenen Fallback-Teils. 

Kotlin:

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

Java:

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

Geben Sie für den Fallback-Parameter einfach null an, wenn Sie den Fallback nicht benötigen.

0
Bret Smith