2013-07-31 11 views
16

Używam Jacksona do czytania wiadomości json. Jedną z wartości, które próbuję analizować, jest lista, a inna wartość zawiera typ danych na liście. To jest struktura, którą utworzyłem w Javie.Jackson przeczytał json w ogólnej liście

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

Przez Class.forName(); Mogę uzyskać klasę reprezentującą dane na liście. Pytanie brzmi, jak mogę odczytać listę.

+0

Może pokażesz nam Twój przykład JSON ciąg i kodu źródłowego, które zostały już napisane? Myślę, że możesz również zobaczyć to pytanie: http://stackoverflow.com/questions/17605524/jackson-delay-deserializing-field/17625688 –

+0

Jeśli nie masz nic przeciwko, zaznacz moją odpowiedź, która sprawiła, że ​​większość punktów jest poprawna jeden. Jest kompaktowy i robi dokładnie to, czego potrzebujesz. – splatch

Odpowiedz

25

Jeśli trzeba mapować przychodzące json do listy można zrobić tak

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

Edit

Coś takiego, zupełnie niesprawdzone i nigdy nie zrobił

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 ... Próbowałem już rozwiązać problem w ten sposób, ale problem polega na tym, że komunikat json ma inne pola oprócz listy. – Lalao

+0

O mój Boże, nie zrozumiałem twojego pytania. Następnie musisz utworzyć deserializer, jak powiedział seralex.vi. Możesz użyć czegoś takiego w środku do deserializacji Listy – alex

+0

Zmieniono moją odpowiedź, daj mi znać, jeśli to zadziała, prawdopodobnie będę musiał zrobić coś podobnego wkrótce – alex

2

trzeba opisywać swoją klasę z @JsonDeserialize(using = MessageDeserializer.class) i wdrożenie niestandardowych Deserializator:

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

przykłady @see tutaj: How Do I Write a Jackson JSON Serializer & Deserializer?

49

coś, co jest znacznie krótsza:

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

To działa. Spróbuj również: Iterator it = mapper.reader (Objects.class) .readValues ​​(in); –

+0

Skąd się bierze obiekt Objects.class? – splatch

+0

Należy do typu, który znajduje się na liście (EntryType na twoim przykładzie) –

-1

Jeśli trzeba czytać json w wykazie leków generycznych, zrobić coś takiego

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

twój obiekt listy jsonowej i Twoja klasa ziarnowa to

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

teraz można przeczytać json przy użyciu HashMap

coś podobnego

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); 
Powiązane problemy