Je développe une application Android qui utilise JSON pour la communication avec le serveur et j’ai un problème étrange lorsque j’essaie d’parsingr mon fichier json.
Ceci est mon json du serveur
{ "street2": null, "province": null, "street1": null, "postalCode": null, "country": null, "city": null }
Ssortingng city = address.optSsortingng("city", "")
la valeur pour City en appelant Ssortingng city = address.optSsortingng("city", "")
sur mon object Json adresse. Pour cette situation, je m’attends à ce que city
soit vide (c’est ce que optSsortingng est là pour ça, n’est-ce pas?) Mais en fait il contient la chaîne “null”. Ainsi, d’autres vérifications null- ou isEmpty renverront false si la chaîne contient du texte. Si j’appelle address.isNull("city")
il renvoie true, ce qui est correct. Seul l’ optSsortingng
échoue.
Je n’ai rien trouvé sur Google ou Stackoverflow pour ce problème. Je ne comprends pas vraiment comment cela peut arriver car je pensais optSsortingng
ferait exactement ce que j’attendais. Quelqu’un sait ce qui ne va pas ici?
Vous n’êtes pas le seul à vous heurter à ce problème et à vous gratter la tête en pensant: «Pourraient-ils vraiment vouloir dire ça? Selon un problème d’AOSP, les ingénieurs de Google ont bien considéré cela comme un bogue , mais ils devaient être compatibles avec l’implémentation org.json, même compatible avec les bogues.
Si vous y réfléchissez, cela a du sens, car si le même code qui utilise les mêmes bibliothèques exécutées dans d’autres environnements Java se comporte différemment dans Android, il y aurait des problèmes de compatibilité majeurs lors de l’utilisation de bibliothèques tierces. Même si les intentions étaient bonnes et que cela corrigeait vraiment les bugs, cela ouvrirait une toute nouvelle boîte de Pandore.
Selon le numéro de l’ AOSP :
Le comportement est intentionnel; Nous nous sums efforcés d’être compatibles avec les erreurs avec org.json. Maintenant que cela est réglé, il est difficile de savoir si nous devrions également corriger notre code. Les applications sont peut-être devenues dépendantes de ce comportement bogué.
Si cela vous cause de la peine, je vous recommande de contourner le problème en utilisant un mécanisme différent pour tester la valeur null, telle que json.isNull ().
Voici une méthode simple pour vous aider:
/** Return the value mapped by the given key, or {@code null} if not present or null. */ public static Ssortingng optSsortingng(JSONObject json, Ssortingng key) { // http://code.google.com/p/android/issues/detail?id=13830 if (json.isNull(key)) return null; else return json.optSsortingng(key, null); }
Vous avez fondamentalement deux choix:
1) Envoyer un payload JSON avec des valeurs nulles
{ "street2": "s2", "province": "p1", "street1": null, "postalCode": null, "country": null, "city": null }
Vous devrez vérifier les valeurs NULL et les parsingr en conséquence:
private Ssortingng optSsortingng_1(final JSONObject json, final Ssortingng key) { return json.isNull(key) ? null : json.optSsortingng(key); }
2) N’envoyez pas les clés avec des valeurs nulles et utilisez directement optSsortingng (key, null) (vous devriez économiser de la bande passante).
{ "street2": "s2", "province": "p1" }
if (json != null && json.getSsortingng(KEY_SUCCESS) != null){ // PARSE RESULT }else{ // SHOW NOTIFICIATION: URL/SERVER NOT REACHABLE
}
c’est pour vérifier json null avec son mot clé.
JSONObject json = new JSONObject("{\"hello\":null}"); json.getSsortingng("hello");
ce que vous obtenez est Ssortingng “null” non null.
votre shoud utiliser
if(json.isNull("hello")) { helloStr = null; } else { helloStr = json.getSsortingng("hello"); }
première vérification avec isNull () …. si ne peut pas travailler alors essayez
et aussi vous avez JSONObject.NULL pour vérifier la valeur NULL …
if ((resultObject.has("username") && null != resultObject.getSsortingng("username") && resultObject.getSsortingng("username").sortingm().length() != 0) { //not null }
et dans votre cas aussi vérifier
resultObject.getSsortingng("username").sortingm().eqauls("null")
Si vous devez d’abord parsingr json et gérer l’object plus tard, essayez ceci:
Analyseur
Object data = json.get("username");
Manutentionnaire
if (data instanceof Integer || data instanceof Double || data instanceof Long) { // handle number ; } else if (data instanceof Ssortingng) { // hanle ssortingng; } else if (data == JSONObject.NULL) { // hanle null; }
Si les valeurs de la clé sont nulles comme ci-dessous
{
“statut”: 200,
“message”: “”,
“Les données”: {
"totalFare": null,
},
}
vérifier avec “isNull”, par exemple pour:
Ssortingng strTotalFare;
if (objResponse.isNull (“totalFare”))
{
strTotalFare = “0”;
} autre {
strTotalFare = objResponse.getSsortingng (“totalFare”);
}
si la valeur est “null” pour la clé “totalFare”, la fonction ci-dessus entrera si et atsortingbue la valeur zéro sinon elle obtiendra la valeur réelle de la clé.
En utilisant la réponse de Matt Quigley comme base, voici le code si vous souhaitez reproduire toutes les fonctionnalités de optSsortingng, y compris la partie de secours, écrite en Kotlin et en Java.
Kotlin:
fun optSsortingng(json: JSONObject, key: Ssortingng, fallback: Ssortingng?): Ssortingng? { var ssortingngToReturn = fallback if (!json.isNull(key)) { ssortingngToReturn = json.optSsortingng(key, null) } return ssortingngToReturn }
Java:
public static Ssortingng optSsortingng(JSONObject json, Ssortingng key, Ssortingng fallback) { Ssortingng ssortingngToReturn = fallback; if (!json.isNull(key)) { ssortingngToReturn = json.optSsortingng(key, null); } return ssortingngToReturn; }
Il suffit de transmettre la valeur null pour le paramètre fallback si vous n’avez pas besoin de la solution de secours.
Mon parsingur Josn a été long et a dû créer une nouvelle classe pour y remédier, puis il a juste fallu append une ligne supplémentaire dans chaque méthode et renommer le nom de propriété JSONObject actuel.
public static ArrayList readNews(Ssortingng json) { if (json != null) { ArrayList 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; }
Voici ma classe avec les méthodes dont j'ai besoin, vous pouvez append plus
public class FixJsonObject { private JSONObject jsonObject; public FixJsonObject(JSONObject jsonObject) { this.jsonObject = jsonObject; } public Ssortingng optSsortingng(Ssortingng key, Ssortingng defaultValue) { if (jsonObject.isNull(key)) { return null; } else { return jsonObject.optSsortingng(key, defaultValue); } } public Ssortingng optSsortingng(Ssortingng key) { return optSsortingng(key, null); } public int optInt(Ssortingng key) { if (jsonObject.isNull(key)) { return 0; } else { return jsonObject.optInt(key, 0); } } public double optDouble(Ssortingng key) { return optDouble(key, 0); } public double optDouble(Ssortingng key, double defaultValue) { if (jsonObject.isNull(key)) { return 0; } else { return jsonObject.optDouble(key, defaultValue); } } public boolean optBoolean(Ssortingng key, boolean defaultValue) { if (jsonObject.isNull(key)) { return false; } else { return jsonObject.optBoolean(key, defaultValue); } } public long optLong(Ssortingng key) { if (jsonObject.isNull(key)) { return 0; } else { return jsonObject.optLong(key, 0); } } public long getLong(Ssortingng key) { return optLong(key); } public Ssortingng getSsortingng(Ssortingng key) { return optSsortingng(key); } public int getInt(Ssortingng key) { return optInt(key); } public double getDouble(Ssortingng key) { return optDouble(key); } public JSONArray getJSONArray(Ssortingng key) { if (jsonObject.isNull(key)) { return null; } else { return jsonObject.optJSONArray(key); } }
}