2011-07-22 17 views
25

Actualmente estoy trabajando en un proyecto de Android que requiere que invoque un servicio web que me devolverá un archivo json. He estado usando la biblioteca GSON para analizar todo el archivo json y obtener un objeto JSON. Ha funcionado bien hasta que me he encontrado con esta información json que los campos clave son dinámicos. Un ejemplo de este archivo es la siguiente:Uso de GSON para analizar un JSON con "clave" y "valor" dinámicos en android

{ "0": { "count":"5"}, 
    "1": { "title":"...", "desc":"" }, 
    "2": { "title":"...", "desc":"" }, 
    "3": { "title":"...", "desc":"" }, 
    "4": { "title":"...", "desc":"" }, 
    "5": { "title":"...", "desc":"" }, 
    "routes": { "route1":"...", "route3":"" }, 
} 

estoy en condiciones de obtener el recuento basado en el ID de la llave de "0", pero no estoy seguro de cómo hago uso de este valor para obtener la otra objetos clave (ID de clave 1-5), que consisten en los datos que necesitaba. Realmente apreciaré si alguien puede ayudarme en este asunto. Gracias.

+0

Me gustaría añadir que si su mapa no está anidado, las cosas son mucho más simples http://stackoverflow.com/questions/2779251/ cómo-puedo-convertir-json-a-un-mapa-de-usar-gson –

Respuesta

30

El enfoque más sencillo que puedo pensar es simplemente tratar la estructura como Map (de Map).

Con Gson, esto es relativamente fácil de hacer, siempre que la estructura Map sea estáticamente conocida, cada rama de la raíz tiene la misma profundidad, y todo es un String.

import java.io.FileReader; 
import java.lang.reflect.Type; 
import java.util.Map; 

import com.google.gson.Gson; 
import com.google.gson.reflect.TypeToken; 

public class GsonFoo 
{ 
    public static void main(String[] args) throws Exception 
    { 
    Gson gson = new Gson(); 
    Type mapType = new TypeToken<Map<String,Map<String, String>>>() {}.getType(); 
    Map<String,Map<String, String>> map = gson.fromJson(new FileReader("input.json"), mapType); 
    System.out.println(map); 

    // Get the count... 
    int count = Integer.parseInt(map.get("0").get("count")); 

    // Get each numbered entry... 
    for (int i = 1; i <= count; i++) 
    { 
     System.out.println("Entry " + i + ":"); 
     Map<String, String> numberedEntry = map.get(String.valueOf(i)); 
     for (String key : numberedEntry.keySet()) 
     System.out.printf("key=%s, value=%s\n", key, numberedEntry.get(key)); 
    } 

    // Get the routes... 
    Map<String, String> routes = map.get("routes"); 

    // Get each route... 
    System.out.println("Routes:"); 
    for (String key : routes.keySet()) 
     System.out.printf("key=%s, value=%s\n", key, routes.get(key)); 
    } 
} 

Para más dinámico el manejo Map estructura, que sugieren fuertemente el cambio a utilizar Jackson, en lugar de Gson, como Jackson deserializar un objeto JSON de cualquier complejidad arbitraria en un Java Map, con sólo una sencilla línea de código, y retendrá automáticamente los tipos de valores primitivos.

import java.io.File; 
import java.util.Map; 

import org.codehaus.jackson.map.ObjectMapper; 

public class JacksonFoo 
{ 
    public static void main(String[] args) throws Exception 
    { 
    ObjectMapper mapper = new ObjectMapper(); 
    Map map = mapper.readValue(new File("input.json"), Map.class); 
    System.out.println(map); 
    } 
} 

Lo mismo se puede lograr con Gson, pero requiere docenas de líneas de código. (Además, Gson tiene otras deficiencias que hacen que valga la pena cambiar a Jackson.)

+0

Hola, gracias por tu solución! Funciona perfectamente. =) – Philip

+2

En Gson actualmente esto funciona: Mapa jsondata = g.fromJson (injson, Map.class); – Teddy

1

Puede obtener los objetos clave individuales utilizando el conteo. Entonces obtendría el objeto "1" y luego obtendría sus objetos "título" y "desc", luego el objeto "2" etc.

+1

He resuelto mi problema usando la solución de Bruce. Gracias por tu ayuda de todos modos. =) – Philip

Cuestiones relacionadas