2013-08-01 2 views
37

ho la seguente classe:deserializzazione in una HashMap di oggetti personalizzati con Jackson

import org.codehaus.jackson.annotate.JsonIgnoreProperties; 
import org.codehaus.jackson.annotate.JsonProperty; 

import java.io.Serializable; 
import java.util.HashMap; 

@JsonIgnoreProperties(ignoreUnknown = true) 
public class Theme implements Serializable { 

    @JsonProperty 
    private String themeName; 

    @JsonProperty 
    private boolean customized; 

    @JsonProperty 
    private HashMap<String, String> descriptor; 

    //...getters and setters for the above properties 
} 

Quando eseguo il seguente codice:

sguardi
HashMap<String, Theme> test = new HashMap<String, Theme>(); 
    Theme t1 = new Theme(); 
    t1.setCustomized(false); 
    t1.setThemeName("theme1"); 
    test.put("theme1", t1); 

    Theme t2 = new Theme(); 
    t2.setCustomized(true); 
    t2.setThemeName("theme2"); 
    t2.setDescriptor(new HashMap<String, String>()); 
    t2.getDescriptor().put("foo", "one"); 
    t2.getDescriptor().put("bar", "two"); 
    test.put("theme2", t2); 
    String json = ""; 
    ObjectMapper mapper = objectMapperFactory.createObjectMapper(); 
    try { 
     json = mapper.writeValueAsString(test); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

La stringa JSON prodotti come questo:

{ 
    "theme2": { 
    "themeName": "theme2", 
    "customized": true, 
    "descriptor": { 
     "foo": "one", 
     "bar": "two" 
    } 
    }, 
    "theme1": { 
    "themeName": "theme1", 
    "customized": false, 
    "descriptor": null 
    } 
} 

Il mio problema è quello di ottenere la stringa json sopra per deserializzare nuovamente in uno

HashMap<String, Theme> 

oggetto.

Il mio codice di de-serializzazione si presenta così:

HashMap<String, Themes> themes = 
     objectMapperFactory.createObjectMapper().readValue(json, HashMap.class); 

Quali de-serializza in un HashMap con i tasti corretti, ma non crea oggetti a tema per i valori. Non so cosa specificare invece di "HashMap.class" nel metodo readValue().

Qualsiasi aiuto sarebbe apprezzato.

risposta

66

Si dovrebbe creare specifico tipo di mappa e di fornire in processo di deserializzazione:

TypeFactory typeFactory = mapper.getTypeFactory(); 
MapType mapType = typeFactory.constructMapType(HashMap.class, String.class, Theme.class); 
HashMap<String, Theme> map = mapper.readValue(json, mapType); 
+0

Ok, stiamo sicuramente andando nella giusta direzione, in quanto è de-serializzazione utilizzando il codice di cui sopra. Tuttavia, l'hashmap viene fornito con una sola chiave/valore (tema2). Ha il tema corretto associato alla chiave, ma theme1 non è nella hashmap? – wbj

+0

Perché no. Per me, app stampa questo quando deserializzo il tuo JSON: '{theme1 = Theme [themeName = theme1, customized = false, descriptor = null], theme2 = Theme [themeName = theme2, customized = true, descriptor = {foo = one, bar = due}]}'. –

+0

Trovato il problema - stringa json scarsamente formata nei miei dati di test. Quindi la tua soluzione funziona come pubblicizzato;) – wbj

12

È possibile utilizzare la classe TypeReference che fa il tipo di fusione per la mappa con i tipi definiti dall'utente. Altro documentazione a http://wiki.fasterxml.com/JacksonInFiveMinutes

ObjectMapper mapper = new ObjectMapper(); 
Map<String,Theme> result = 
    mapper.readValue(src, new TypeReference<Map<String,Theme>>() {});