2010-09-22 10 views
12

Estoy usando gson para analizar json en beans Java. Para la API que estoy usando, una gran cantidad de los resultados json incluyen el resultado como la primera propiedad de un objeto json. La "manera gson" parece ser la creación de un objeto Java envoltorio equivalente, que tiene una propiedad para el tipo de salida objetivo, pero esto da como resultado clases desechables innecesarias. ¿Hay alguna forma de hacer esto mejor?¿Cuál es la forma más fácil de analizar json usando gson cuando el elemento a analizar es un elemento de una cadena json?

Por ejemplo, para analizar: {"profile":{"username":"nickstreet","first_name":"Nick","last_name":"Street"}}

tengo que hacer:

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

Por supuesto un enfoque alternativo a la utilización de un recipiente sería eliminar manualmente la porción exterior de la cadena (es decir, eliminar el "perfil": {y cierre}) utilizando técnicas estándar de análisis de cadenas, pero este parece ser el enfoque equivocado.

Me gustaría ser capaz de hacer algo como:

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

This issue sugiere que debería ser posible para romper una cadena JSON hasta en un objeto JSON, para sacar un jsonElement de este objeto, y pasar en json.fromJson(). Sin embargo, el método toJsonElement() solo funciona en un objeto java, no en una cadena json.

¿Alguien tiene un mejor enfoque?

Respuesta

8

Me encontré con el mismo problema. Básicamente, lo que debes hacer para evitar toda la tontería de la clase contenedor es simplemente usar funciones JSONObject para recuperar el objeto interno que estás tratando de deserializar. Perdóneme por el código descuidado pero dice algo así:

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

Gracias por la respuesta. No es del todo correcto, pero me llevó a la respuesta correcta. No puede crear directamente un JsonObject con una cadena, debe usar JsonParser para crearlo. JsonParser parser = new JsonParser(); JsonObject j = (JsonObject) parser.parse (json); –

Cuestiones relacionadas