2012-07-16 20 views
12

Sto utilizzando Jackson 1.9.5 in un progetto Android per analizzare i file JSON.Jackson ObjectMapper con chiavi JSON arbitrarie

Finora non ho avuto alcun problema, e può analizzare i file bene utilizzando il seguente codice:

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

dove la classe DetailSchema è costituito da un mix di tipi primitivi e classi. Ora sto correndo in un problema dove voglio analizzare alcuni JSON come la seguente:

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

Dove Non posso conoscere le chiavi mappa prima mano (possono essere definite dall'utente). Pertanto, non sono sicuro di come dovrebbe essere la classe Java associata.

Vale a dire, per questo esempio, potrebbe apparire come:

public class MyClass { 

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

} 

Ma questo potrebbe non essere corretto per un'altra istanza del file JSON. Idealmente ho bisogno di un modo per Jackson per mappare valori a qualcosa come un NameValuePair. Sospetto che la mappatura automatica degli oggetti non possa essere un'opzione in questo caso: qualcuno può confermare o negare questo?

risposta

16

Hai due opzioni. O è possibile utilizzare readTree in ObjectMapper, che restituisce un JsonNode. Lavorare con un JsonNode è molto simile a lavorare con un albero, in modo da poter ottenere i nodi figli, leggere i valori, eccetera:

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

Allora avresti bisogno di costruire l'oggetto DetailSchema manualmente.

In alternativa, è possibile lasciare Jackson deserializzare come una mappa, nel qual caso ci si utilizza il codice, ma in cui MyClass sarebbe stato così:

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

    // getter/setters 
} 

Probabilmente si può digitare i valori della mappa come String come bene se sei sicuro che gli input sono testo in json. (In realtà, non sono sicuro di quale tipo di applicazione Jackson fa, forse comunque lo permetterà comunque ...)

+1

Grazie mille! Una mappa funzionerà bene per i miei scopi. – aaronsnoswell

+0

In realtà non è necessario utilizzare una classe personalizzata per ottenere una 'Mappa', si può avere la deserializzazione di Jackson direttamente su un'implementazione dell'interfaccia' Mappa', ad es .: 'Mappa jsonFields = mapper.readValue (ifp, HashMap .class) ' – brianmearns

Problemi correlati