La risposta dipende da quanto si ha fiducia che JSON :) Certo, potrebbe essere venuta dalla vostra applicazione, ma se inserire qualche input dell'utente non attendibile, si trovano ad affrontare una possibile sicurezza buco.
Quindi:
- per JSONs da fonti attendibili, io uso JavaScript Overlay Types. Rendono l'integrazione di JSON con GWT senza soluzione di continuità e raccomando senz'altro questo approccio. Tuttavia, internamente, questo chiama la funzione
eval()
che significa (almeno) due cose: l'analisi JSON sarà estremamente veloce (utilizza il codice nativo del browser per quello) e sarà probabilmente insicura. Google per ulteriori informazioni sui problemi di sicurezza relativi a JSON. JSONParser
può anche analizzare JSON tramite eval()
, quando si richiama il metodo parseLenient(String jsonString)
, ma è decisamente meno attraente di JSO.
- per non attendibile fonti/ingresso, è necessario utilizzare
JSONParser
via JSONParser.parseStrict(String jsonString)
(disponibile in GWT> = 2.1) - dovrete scrivere più codice in questo modo, ma si può essere sicuri che l'ingresso è gestita correttamente. Potresti anche considerare l'integrazione del "ufficiale" JSON parser from json.org con JSO - scrivere una funzione JSNI che restituisce l'oggetto analizzato e lanciarlo sul tuo JSO - in teoria è dovrebbe funzionare;) (questo è ciò che GWT fa internamente con JSOs, almeno da quello che ho capito)
per quanto riguarda l'accesso a liste in JSON, ci sono classi appropriate per questo: JsArray
(generica, per gli elenchi di altri JSOs), JsArrayString
, ecc Se si guarda alla loro realizzazione, sono solo I wrapper JSNI intorno agli array JS nativi, quindi sono molto veloci (ma limitati, per qualche motivo).
Modifica in risposta al commento di Tim:
ho scritto una semplice classe astratta che aiuta a ridurre al minimo il codice standard, quando si tratta di JSOs e JSON:
import com.google.gwt.core.client.JavaScriptObject;
public abstract class BaseResponse extends JavaScriptObject {
// You can add some static fields here, like status codes, etc.
/**
* Required by {@link JavaScriptObject}
*/
protected BaseResponse() { }
/**
* Uses <code>eval</code> to parse a JSON response from the server
*
* @param responseString the raw string containing the JSON repsonse
* @return an JavaScriptObject, already cast to an appropriate type
*/
public static final native <T extends BaseResponse> T getResponse(String responseString) /*-{
// You should be able to use a safe parser here
// (like the one from json.org)
return eval('(' + responseString + ')');
}-*/;
}
Poi si scrivi il tuo vero JSO in quanto tale:
import com.example.client.model.User;
public class LoginResponse extends BaseResponse {
protected LoginResponse() { }
public final native String getToken() /*-{
return this.t;
}-*/;
public final native int getId() /*-{
return parseInt(this.u[0]);
}-*/;
// ...
// Helper method for converting this JSO to a POJO
public final User getUser() {
return new User(getLogin(), getName(), getLastName());
}
}
E finalmente nel codice:
// response.getText() contains the JSON string
LoginResponse loginResponse = LoginResponse.getResponse(response.getText());
//^no need for a cast \o/
tuo JSON si presenta così (per gentile concessione di JSONLint, un grande JSON validatore):
{
"item": [
{
"Id": "1",
"Name": "Bob"
},
{
"Id": "2",
"Name": "John"
},
{
"Id": "3",
"Name": "Bill"
}
]
}
Quindi, mi piacerebbe scrivere un OCS che descrive le voci di tale elenco:
public class TestResponse extends BaseResponse {
protected TestResponse() { }
public final native String getId() /*-{
return this.Id;
}-*/;
public final native String getName() /*-{
return this.Name;
}-*/;
// Static helper for returning just the list
// Code untested but you should get the idea ;)
public static final native JsArray<TestResponse> getTestList(String json) /*-{
var stuff = eval('(' + json + ')');
return stuff.item;
}-*/;
}
Poi, nel codice si chiama TestResponse.getTestList(someJsonString)
e giocare con la JsArray
(gli TestResponse
s che contiene sono creati automaticamente). Fantastico, eh? ;) Potrebbe essere un po 'di confusione in un primo momento, ma credetemi, sarà un senso una volta che si inizia ad usarlo ed è molto più facile che il parsing tramite JSONParser
> _>
Grazie per il vostro aiuto, ho intenzione usare i tipi di sovrapposizione js. Ma come tradurrei il mio testo JSON per ottenere un cliente? Nell'esempio, usa: $ wnd.jsonData [0]; Nel mio caso ho una stringa (proveniente da un RequestBuilder) – Tim
perfettamente funzionante, grazie. Ho perso la funzione eval. Con i migliori saluti – Tim
Perché hai usato le parentesi graffe attorno alla stringa in eval? In questo codice: 'return eval ('(' + responseString + ')');' – Davor