First create a mapper :
import com.fasterxml.jackson.databind.ObjectMapper;// in play 2.3
ObjectMapper mapper = new ObjectMapper();
As Array:
MyClass[] myObjects = mapper.readValue(json, MyClass[].class);
As List:
List<MyClass> myObjects = mapper.readValue(jsonInput, new TypeReference<List<MyClass>>(){});
Another way to specify the List type:
List<MyClass> myObjects = mapper.readValue(jsonInput, mapper.getTypeFactory().constructCollectionType(List.class, MyClass.class));
Answer from Programmer Bruce on Stack OverflowFirst create a mapper :
import com.fasterxml.jackson.databind.ObjectMapper;// in play 2.3
ObjectMapper mapper = new ObjectMapper();
As Array:
MyClass[] myObjects = mapper.readValue(json, MyClass[].class);
As List:
List<MyClass> myObjects = mapper.readValue(jsonInput, new TypeReference<List<MyClass>>(){});
Another way to specify the List type:
List<MyClass> myObjects = mapper.readValue(jsonInput, mapper.getTypeFactory().constructCollectionType(List.class, MyClass.class));
From Eugene Tskhovrebov
List<MyClass> myObjects = Arrays.asList(mapper.readValue(json, MyClass[].class))
This solution seems to be the best for me.
The TypeFactory in Jackson allows to map directly to collections and other complex types:
String json = "[ \"abc\", \"def\" ]";
ObjectMapper mapper = new ObjectMapper();
List<String> list = mapper.readValue(json, TypeFactory.defaultInstance().constructCollectionType(List.class, String.class));
You could define a wrapper class as following:
public class Wrapper {
private List<String> values;
// Default constructor, getters and setters omitted
}
Then use:
Wrapper wrapper = mapper.readValue(json, Wrapper.class);
List<String> values = wrapper.getValues();
If you want to avoid a wrapper class, try the following:
JsonNode valuesNode = mapper.readTree(json).get("values");
List<String> values = new ArrayList<>();
for (JsonNode node : valuesNode) {
values.add(node.asText());
}
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>>() {}
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;
}
First, define POJOs for mapping your request object:
public class RequestObj implements Serializable{
private List<Long> ids;
private UsuarioDTO user;
/* getters and setters here */
}
public class UsuarioDTO implements Serializable{
private String name;
private String email;
/* getters and setters here */
}
And then modify your endpoint:
@PostMapping(value = "/sendToOficial")
public ResponseEntity<?> sendToOficial(@RequestBody RequestObj payload) {
In this way you also do not need to use an ObjectMapper. Just call payload.getIds().
Consider also that in this way if payload changes you'll need only to change RequestObj definition, while using ObjectMapper would force you to update also your endpoint in an important way. It's better and safer to separate payload representation from control logic.
If you just want your mapper to read into a List<Long>, use this trick for obtaining full generics type information by sub-classing.
Example
ObjectMapper mapper = new ObjectMapper();
List<Long>listOfLong=mapper.readValue("[ 123421, 15643, 51243]" ,
new TypeReference<List<Long>>() {
});
System.out.println(listOfLong);
Prints
[123421, 15643, 51243]