2013-08-14 16 views
39

Sto sviluppando un'applicazione Android che utilizza JSON per la comunicazione con il server e ho uno strano problema quando sto cercando di analizzare il mio file json.JSON jsonObject.optString() restituisce String "null"

Questo è il mio JSON dal server

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

sto ottenendo il valore per Città chiamando String city = address.optString("city", "") sul mio indirizzo JSON-oggetto. Per questa situazione mi aspetto che lo city sia vuoto (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 vero 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 lo optString avrebbe fatto esattamente quello che mi aspettavo. Qualcuno sa cosa sta andando storto qui?

+2

'null' è un valore valido per una stringa in java (e ogni altro linguaggio di programmazione che conosco), quindi ha senso che non scelga il fallback, se la chiave semplicemente non esistesse, ci vorrebbe il fallback – x4rf41

+0

Grazie. Non è il comportamento che mi aspettavo da _optString_ ma sembra che lo sviluppatore avesse in mente qualcosa di diverso. Devo fare il controllo da solo. – joshplusa

risposta

72

Non siete soli in esecuzione in questo problema e grattarsi la testa, pensando "Potevano veramente hanno fatto sì questo?" Secondo un problema AOSP, gli ingegneri di Google hanno fattoconsiderano un errore, ma dovevano essere compatibili con l'implementazione org.json, anche con bug-compatibili.

Se ci pensate, ha senso, perché se lo stesso codice che utilizza le stesse librerie eseguite in altri ambienti Java si comporta diversamente in Android, ci sarebbero maggiori problemi di compatibilità quando si usano librerie di terze parti. Anche se le intenzioni erano buone e risolvevano i bug, si apriva una nuova lattina di worm.

Secondo il AOSP issue:

il comportamento è intenzionale; abbiamo fatto tutto il possibile per essere compatibili con bug con org.json. Ora che è stato risolto, non è chiaro se sia necessario correggere anche il nostro codice. Le applicazioni potrebbero aver fatto affidamento su questo comportamento bacato.

Se ciò causa fastidio, è consigliabile risolvere il problema utilizzando un meccanismo diverso per verificare null, come json.isNull().

Ecco un metodo semplice per aiutarvi:

/** 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); 
} 
+0

Perché chiamare 'json.optString (chiave, null)' e non solo 'json.getString (chiave)' in il tuo metodo personalizzato? –

+0

Il metodo helper è una sostituzione di 'optString' non' getString'. 'opt' significa _optional_ e non genererà un'eccezione se la chiave non esiste. –

22

Che, fondamentalmente, hanno 2 scelte:

1) invia una payload JSON con valori nulli

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

Si dovrà verificare la presenza di valori nulli e analizzare 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" 
} 
+2

+1 per json.isNull (chiave), causa if (json.get (chiave) == null) non funziona correttamente –

+0

Provare if (json.get (chiave) .equals ("null).) – DevAndroid

+1

Attenzione: json.optString (chiave) restituirà una stringa vuota se la chiave non viene trovata –

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

}

che è per il controllo JSON nulla con là parola chiave.

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

questo si ottiene stringa "null" non null.

tua shoud utilizzare

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

primo controllo con isNull() .... se cant lavoro quindi provare belows

e inoltre si hanno JSONObject.NULL controllare valore nullo ...

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

e nel tuo caso controllare anche

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

Se è necessario analizzare JSON prima e gestire opporsi in seguito, lasciare che prova questo

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

Se i valori per la chiave è nullo come qui di seguito

{

"stato": 200,

"messaggio": "",

"dati": {

"totalFare": null, 

},

}

controllo con "isNull", per esempio:

String strTotalFare;

se (objResponse.isNull ("totalFare"))

{

strTotalFare = "0";

} else {

strTotalFare = objResponse.getString ("totalFare");

}

se il valore è "nullo" per la chiave "totalFare", sopra la funzione entrerà in se e assegnare valore zero altrimenti otterrà valore effettivo da chiave.

0

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

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

semplicemente passare a null per il parametro fallback se non è necessario il fallback.

Problemi correlati