
Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:
Once the early-adopter seats are all used, the price will go up and stay at $33/year.
Last updated: April 26, 2024
This tutorial will show how to deserialize a JSON Array to a Java Array or Collection with Jackson 2.
If you want to dig deeper and learn other cool things you can do with the Jackson 2 – head on over to the main Jackson tutorial.
Jackson can easily deserialize to a Java Array:
@Test
public void givenJsonArray_whenDeserializingAsArray_thenCorrect()
throws JsonParseException, JsonMappingException, IOException {
ObjectMapper mapper = new ObjectMapper();
List<MyDto> listOfDtos = Lists.newArrayList(
new MyDto("a", 1, true), new MyDto("bc", 3, false));
String jsonArray = mapper.writeValueAsString(listOfDtos);
// [{"stringValue":"a","intValue":1,"booleanValue":true},
// {"stringValue":"bc","intValue":3,"booleanValue":false}]
MyDto[] asArray = mapper.readValue(jsonArray, MyDto[].class);
assertThat(asArray[0], instanceOf(MyDto.class));
}
Reading the same JSON Array into a Java Collection is a bit more difficult – by default, Jackson will not be able to get the full generic type information and will instead create a collection of LinkedHashMap instances:
@Test
public void givenJsonArray_whenDeserializingAsListWithNoTypeInfo_thenNotCorrect()
throws JsonParseException, JsonMappingException, IOException {
ObjectMapper mapper = new ObjectMapper();
List<MyDto> listOfDtos = Lists.newArrayList(
new MyDto("a", 1, true), new MyDto("bc", 3, false));
String jsonArray = mapper.writeValueAsString(listOfDtos);
List<MyDto> asList = mapper.readValue(jsonArray, List.class);
assertThat((Object) asList.get(0), instanceOf(LinkedHashMap.class));
}
There are two ways to help Jackson understand the right type information – we can either use the TypeReference provided by the library for this very purpose:
@Test
public void givenJsonArray_whenDeserializingAsListWithTypeReferenceHelp_thenCorrect()
throws JsonParseException, JsonMappingException, IOException {
ObjectMapper mapper = new ObjectMapper();
List<MyDto> listOfDtos = Lists.newArrayList(
new MyDto("a", 1, true), new MyDto("bc", 3, false));
String jsonArray = mapper.writeValueAsString(listOfDtos);
List<MyDto> asList = mapper.readValue(
jsonArray, new TypeReference<List<MyDto>>() { });
assertThat(asList.get(0), instanceOf(MyDto.class));
}
Or we can use the overloaded readValue method that accepts a JavaType:
@Test
public void givenJsonArray_whenDeserializingAsListWithJavaTypeHelp_thenCorrect()
throws JsonParseException, JsonMappingException, IOException {
ObjectMapper mapper = new ObjectMapper();
List<MyDto> listOfDtos = Lists.newArrayList(
new MyDto("a", 1, true), new MyDto("bc", 3, false));
String jsonArray = mapper.writeValueAsString(listOfDtos);
CollectionType javaType = mapper.getTypeFactory()
.constructCollectionType(List.class, MyDto.class);
List<MyDto> asList = mapper.readValue(jsonArray, javaType);
assertThat(asList.get(0), instanceOf(MyDto.class));
}
One final note is that the MyDto class needs to have the no-args default constructor – if it doesn’t, Jackson will not be able to instantiate it:
com.fasterxml.jackson.databind.JsonMappingException:
No suitable constructor found for type [simple type, class org.baeldung.jackson.ignore.MyDto]:
can not instantiate from JSON object (need to add/enable type information?)
Alternatively, we can use the @JsonCreator annotation to adjust the constructor used in deserialization.
Mapping JSON arrays to java collections is one of the more common tasks that Jackson is used for, and these solutions are vital to getting to a correct, type-safe mapping.