Let's get started with a Microservice Architecture with Spring Cloud:
Jackson – Unmarshall to Collection/Array
Last updated: April 26, 2024
1. Overview
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.
2. Unmarshall to Array
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));
}
3. Unmarshall to Collection
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.
4. Conclusion
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.
The code backing this article is available on GitHub. Once you're logged in as a Baeldung Pro Member, start learning and coding on the project.
















