Reputation: 423
I'm using Jackson in order to read json messages. One of the values that I' trying to parse is a List and another value contains the type of the data in the list. This is the structure i 've created in java.
public class Message<T> {
private Timestamp time;
private RestAction action;
private String type;
private List<T> data;
}
Through Class.forName();
I can get the class which represents the data in the list. The question is how can I read the List.
Upvotes: 40
Views: 83909
Reputation: 220
This should work for simple POJO and Collections:
// import com.fasterxml.jackson.core.type.TypeReference;
// import com.fasterxml.jackson.databind.ObjectMapper;
// get your <T> type
final Type entryType = ...
// Create a new TypeReference object and convert
return new ObjectMapper().readValue(jsonString, new TypeReference<>() {
@Override
public Type getType() {
return entryType;
}
});
Upvotes: 0
Reputation: 1599
Something which is much shorter:
mapper.readValue(jsonString, new TypeReference<List<EntryType>>() {});
Where EntryType
is a reference to type you would like to hold within collection. It might be any Java class.
For example to read JSON representation such as ["a", "b", "c"]
second argument to mapper should be new TypeReference<List<String>>() {}
Upvotes: 104
Reputation: 30285
Since version 2.11 (Apr 2020) Jackson has readerForListOf
method (documentation):
ObjectMapper mapper = ObjectMapper().configure(...);
ObjectReader reader = mapper.readerForListOf(MyClass.class);
List<MyClass> list = reader.readValue(...);
Upvotes: 9
Reputation: 7
If you need to read json in generic List, Do something like
{
Employee:
[
{
"key": "value",
"key": "value"
},
{
"key": "value",
"key": "value"
}
]
}
your json list object and your bean class is
class person {
private String key;
private String value;
}
now you can read this json using HashMap
something like
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);
Upvotes: -2
Reputation: 3442
If you need to map the incoming json to your List you can do like this
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
Something like this, completly untested and never done
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;
}
Upvotes: 74
Reputation: 620
You need to annotate your class with @JsonDeserialize(using = MessageDeserializer.class)
and implement custom deserializer:
public class MessageDeserializer extends JsonDeserializer<Message> {
@Override
public Message deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
throws IOException, JsonProcessingException {
// YOU DESERIALIZER CODE HERE
}
}
@see examples here: How Do I Write a Jackson JSON Serializer & Deserializer?
Upvotes: 4