Jackson 数组映射到 java 集合
Contents
1. 概述
本教程将展示如何使用 Jackson 2 将 JSON 数组反序列化为 Java 数组或集合。
如果您想更深入地挖掘并学习可以使用 Jackson 2 做的其他很酷的事情。
2. 列表到数组
Jackson 可以轻松反序列化为 Java 数组:
@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. 列表到集合
将相同的 JSON 数组读入 Java 集合有点困难——默认情况下,Jackson 将无法获得完整的泛型类型信息,而是创建一个LinkedHashMap实例的集合:
@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));
}
有两种方法可以帮助 Jackson 理解正确的类型信息——我们可以使用库提供的TypeReference来达到这个目的:
@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));
}
或者我们可以使用接受JavaType的重载readValue方法:
@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));
}
最后一点是MyDto类需要有无参数默认构造函数——如果没有,Jackson 将无法实例化它:
com.fasterxml.jackson.databind.JsonMappingException:
No suitable constructor found for type [simple type, class com.blogdemo.jackson.ignore.MyDto]:
can not instantiate from JSON object (need to add/enable type information?)