2012-07-16 20 views
12

Estoy usando Jackson 1.9.5 en un proyecto de Android para analizar archivos JSON.Jackson ObjectMapper con claves JSON arbitrarias

Hasta ahora no he tenido ningún problema, y ​​puede analizar archivos fina utilizando el siguiente código:

AssetManager mgr = getAssets(); 
ObjectMapper mapper = new ObjectMapper(); 

try { 
    InputStream ifp = mgr.open("detail_schema.json"); 
    schema = mapper.readValue(ifp, DetailSchema.class); 
} catch (IOException e) { 
    e.printStackTrace(); 
} 

donde la clase DetailSchema consiste en una mezcla de tipos primitivos y clases. Ahora estoy corriendo en un problema donde quiero analizar algunos JSON como el siguiente:

"fields": { 
    "Suburb": "Paddington", 
    "State": "NSW", 
    "Post Code": "2074", 
    "Lollipop": "Foo Bar Haz" 
} 

Donde no me es posible conocer las claves mapa antes de mano (que puede ser definida por el usuario). Como tal, no estoy seguro de cómo debería ser la clase Java asociada.

Es decir, para este ejemplo, podría parecer:

public class MyClass { 

    public String Suburb; 
    public String State; 
    public String PostCode; 
    public String Lollipop; 

} 

Pero esto puede no ser correcto para otra instancia del archivo JSON. Idealmente, necesito alguna forma para que Jackson asigne valores a algo como NameValuePair. Sospecho que el mapeo automático de objetos puede no ser una opción en este caso. ¿Puede alguien confirmar o negar esto?

Respuesta

16

Tiene dos opciones. O bien puede usar readTree in ObjectMapper, que devuelve JsonNode. Trabajar con un JsonNode es parecido al funcionamiento de un árbol, para que pueda obtener los nodos hijos, leer valores, etcétera:

InputStream ifp = mgr.open("detail_schema.json"); 
JsonNode root = mapper.readTree(ifp); 
JsonNode fields = root.get("fields"); 
for (JsonNode children : fields.getElements()) { 
    // ... 
} 

Entonces será necesario para construir su objeto DetailSchema manualmente.

O bien, puede dejar que Jackson deserializar como un mapa, en cuyo caso tendrá que utilizar su código, pero siendo MiClase sería así:

public class MyClass { 
    public Map<String, Object> fields; 

    // getter/setters 
} 

es probable que pueda escribir los valores de mapa como String como bien si está seguro de que las entradas son texto en json. (En realidad, no estoy seguro de qué tipo de aplicación Jackson hace, tal vez permitirá algo de todos modos ...)

+1

¡Muchas gracias! Un mapa funcionará bien para mis propósitos. – aaronsnoswell

+0

En realidad no tiene que usar una clase personalizada para obtener un 'Mapa', puede hacer que Jackson se deserialice directamente a una implementación de la interfaz' Mapa', por ejemplo: 'Map jsonFields = mapper.readValue (ifp, HashMap .class) ' – brianmearns

Cuestiones relacionadas