2013-07-31 17 views
16

Sto usando Jackson per leggere messaggi json. Uno dei valori che sto cercando di analizzare è un elenco e un altro valore contiene il tipo di dati nell'elenco. Questa è la struttura che ho creato in Java.Jackson legge json nell'elenco generico

public class Message<T> { 
    private Timestamp time; 
    private RestAction action; 
    private String type; 
    private List<T> data; 
} 

Attraverso Class.forName(); posso ottenere la classe che rappresenta i dati nella lista. La domanda è come posso leggere la lista.

+0

Potete mostrare a noi il vostro esempio stringa JSON e il codice sorgente che si hanno già scritto? Penso che puoi anche vedere questa domanda: http://stackoverflow.com/questions/17605524/jackson-delay-deserializing-field/17625688 –

+0

Se non ti dispiace, segnare la mia risposta che ha ottenuto la maggior parte dei punti come valida uno. È compatto e fa esattamente ciò di cui hai bisogno. – splatch

risposta

25

Se è necessario mappare il JSON in entrata nella tua lista che si può fare in questo modo

String jsonString = ...; //Your incoming json string 
ObjectMapper mapper = new ObjectMapper(); 
Class<?> clz = Class.forName(yourTypeString); 
JavaType type = mapper.getTypeFactory().constructCollectionType(List.class, clz); 
List <T> result = mapper.readValue(jsonString, type); 

Modifica

Qualcosa di simile, completamente testato e mai fatto

public Message<T> deserialize(JsonParser jsonParser, DeserializationContext arg1) 
    throws IOException, JsonProcessingException { 
    ObjectMapper mapper = new ObjectMapper(); 
    ObjectCodec oc = jsonParser.getCodec(); 
    JsonNode node = oc.readTree(jsonParser); 

    JsonNode timeStamp = node.get("time"); 
    Timestamp time = mapper.readValue(timeStamp, Timestamp.class); 
    JsonNode restAction = node.get("action"); 
    RestAction action = mapper.readValue(restAction, RestAction.class); 
    String type = node.get("type").getTextValue(); 
    Class<?> clz = Class.forName(type); 
    JsonNode list = node.get("data"); 
    JavaType listType = mapper.getTypeFactory().constructCollectionType(List.class, clz); 
    List <T> data = mapper.readValue(list, listType); 

    Message<T> message = new Message<T>; 
    message.setTime(time); 
    message.setAction(action); 
    message.setType(type); 
    message.setData(data); 

    return message; 
} 
+0

Ok ... Ho già provato a risolverlo in questo modo ma il problema è che il messaggio json ha altri campi oltre alla lista. – Lalao

+0

Oops mio male, non ho capito la tua domanda. Quindi è necessario creare un deserializzatore come seralex.vi detto. Puoi usare qualcosa di simile al suo interno per deserializzare la Lista – alex

+0

Modificata la mia risposta, fammi sapere se funziona, probabilmente dovrò fare qualcosa di simile presto – alex

2

È necessario annotare la classe con @JsonDeserialize(using = MessageDeserializer.class) e implementare deserializzatore personalizzato:

public class MessageDeserializer extends JsonDeserializer<Message> { 
    @Override 
    public Message deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) 
    throws IOException, JsonProcessingException { 
    // YOU DESERIALIZER CODE HERE 
    } 
} 

esempi @see qui: How Do I Write a Jackson JSON Serializer & Deserializer?

49

Qualcosa che è molto più breve:

mapper.readValue(jsonString, new TypeReference<List<EntryType>>() {}); 
+0

Funziona. Prova anche questo: Iterator it = mapper.reader (Objects.class) .readValues ​​(in); –

+0

Da dove proviene Objects.class? – splatch

+0

Appartiene al tipo che si trova nell'elenco (EntryType nell'esempio) –

-1

Se avete bisogno di leggere JSON in elenco generico, fare qualcosa di simile

{ 
    Employee: 
    [ 
     { 
      "key": "value", 
      "key": "value" 
     }, 
     { 
      "key": "value", 
      "key": "value" 
     } 
    ] 
} 

l'oggetto lista json e la classe bean è

class person { 
private String key; 
private String value; 
} 

ora si può leggere questo JSON utilizzando HashMap

qualcosa come

TypeReference<HashMap<String,List<Person>>> personList = new TypeReference<HashMap<String, List<Person>>>() {}; 

ObjectMapper objectMapper = new ObjectMapper(); 
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); 
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 

HashMap<String, List<Person>> employees = objectMapper.readValue(request.getInputStream(), personList); 
Problemi correlati