java - retrieve - save json android studio




JSON jsonObject.optString() restituisce String "null" (4)

Sto sviluppando un'applicazione per Android che usa JSON per la comunicazione con il server e ho uno strano problema quando sto cercando di analizzare il mio file json.

Questo è il mio json dal server

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

Sto ottenendo il valore per City chiamando String city = address.optString("city", "") sul mio indirizzo Json-object. Per questa situazione mi aspetto che la city sia vuota (questo è ciò che optString è qui per non è vero?) Ma in realtà contiene la stringa "null". Quindi ulteriori controlli null o isEmpty restituiranno false poiché la stringa contiene testo. Se chiamo address.isNull("city") restituisce true che è corretto. Solo optString non riesce.

Non ho trovato nulla su Google o StackOverflow per questo problema. Non capisco davvero come possa accadere come pensavo che optString avrebbe fatto esattamente quello che mi aspettavo. Qualcuno sa cosa sta andando storto qui?


Fondamentalmente hai 2 scelte:

1) Invia un payload JSON con valori nulli

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

Dovrai controllare i valori nulli e analizzarli di conseguenza:

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

2) Non inviare le chiavi con valori null e utilizzare optString (chiave, null) direttamente (dovrebbe risparmiare larghezza di banda).

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

Il mio parser Josn era lungo e dovevo creare una nuova classe per risolverlo, quindi ho dovuto aggiungere 1 riga in più in ogni metodo e rinominare il nome della proprietà JSONObject corrente, quindi tutte le altre chiamate facevano riferimento alla mia nuova classe anziché a JSONObject.

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

Ecco la mia classe con i metodi di cui avevo bisogno, puoi aggiungerne altri

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

}


Se i valori per la chiave sono nulli come di seguito

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

se il valore è "null" per la chiave "totalFare", la funzione precedente entrerà in se e assegnerà il valore zero altrimenti otterrà il valore effettivo dalla chiave.


Utilizzando la risposta di Matt Quigley come base, ecco il codice se desideri imitare la funzionalità completa di optString, inclusa la parte di fallback, scritta in Kotlin e Java.

Kotlin:

"totalFare": null,

Giava:

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

Basta passare in null per il parametro fallback se non hai bisogno del fallback.







json