2010-09-22 10 views
12

Sto usando gson per analizzare json in java bean. Per l'API che sto utilizzando, un numero elevato di risultati JSON include il risultato come prima proprietà di un oggetto json. Il "modo gson" sembra essere quello di creare un oggetto java wrapper equivalente, che ha una proprietà per il tipo di output di destinazione, ma questo comporta inutili classi di estrazione. C'è un modo migliore di farlo?Qual è il modo più semplice per analizzare JSON usando gson quando l'elemento da analizzare è un elemento di una stringa json?

Ad esempio per analizzare: {"profile":{"username":"nickstreet","first_name":"Nick","last_name":"Street"}}

devo fare:

public class ParseProfile extends TestCase { 
    public void testParseProfile() { 
     Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create(); 
     String profileJson = "{\"profile\":{\"username\":\"nickstreet\",\"first_name\":\"Nick\",\"last_name\":\"Street\"}}"; 
     ProfileContainer profileContainer = gson.fromJson(profileJson, ProfileContainer.class); 
     Profile profile = profileContainer.getProfile(); 
     assertEquals("nickstreet", profile.username); 
     assertEquals("Nick", profile.firstName); 
     assertEquals("Street", profile.lastName); 
    } 
} 

public class ProfileContainer { 
    protected Profile profile; 

    public Profile getProfile() { 
     return profile; 
    } 

    public void setProfile(Profile profile) { 
     this.profile = profile; 
    } 
} 

public class Profile { 
    protected String username; 
    protected String firstName; 
    protected String lastName; 

    public String getUsername() { 
     return username; 
    } 
    public void setUsername(String username) { 
     this.username = username; 
    } 
    public String getFirstName() { 
     return firstName; 
    } 
    public void setFirstName(String firstName) { 
     this.firstName = firstName; 
    } 
    public String getLastName() { 
     return lastName; 
    } 
    public void setLastName(String lastName) { 
     this.lastName = lastName; 
    } 
} 

Naturalmente un approccio alternativo all'uso di un contenitore potrebbe essere quella di rimuovere manualmente la porzione esterna della stringa (cioè rimuovere il "profilo": {e chiusura}) usando le tecniche standard di analisi delle stringhe, ma questo sembra l'approccio sbagliato.

mi piacerebbe essere in grado di fare qualcosa di simile:

Profile p = gson.fromJsonProperty(json, Profile.class, "profile"); 

This issue suggerisce dovrebbe essere possibile per rompere una stringa JSON in su in un oggetto JSON, per tirare fuori un jsonElement da questo oggetto e passare in json.fromJson(). Tuttavia, il metodo toJsonElement() funziona solo su un oggetto java, non su una stringa json.

Qualcuno ha un approccio migliore?

risposta

8

Mi sono imbattuto nello stesso problema. Fondamentalmente ciò che si fa per evitare tutte le sciocchezze della classe container è semplicemente utilizzare le funzioni JSONObject per recuperare l'oggetto interno che si sta tentando di deserializzare. Perdonami per il codice sciatto ma va qualcosa del genere:

GsonBuilder gsonb = new GsonBuilder() 
Gson gson = gsonb.create(); 

JSONObject j; 
JSONObject jo; 

Profile p = null; 

try { 

    j = new JSONObject(convertStreamToString(responseStream)); 
    jo = j.getJSONObject("profile"); // now jo contains only data within "profile" 
    p = gson.fromJson(jo.toString(), Profile.class); 
    // now p is your deserialized profile object 
}catch(Exception e) { 
    e.printStackTrace(); 
} 
+2

Grazie per la risposta. Non è del tutto corretto, ma mi ha portato alla risposta corretta. Non è possibile creare direttamente un oggetto JsonObject con una stringa, è necessario utilizzare JsonParser per crearlo. parser JsonParser = new JsonParser(); JsonObject j = (JsonObject) parser.parse (json); –

Problemi correlati