Джаксън - Unmarshall към Collection / Array

1. Общ преглед

Този урок ще покаже как да десериализирате JSON масив към Java масив или колекция с Jackson 2 .

Ако искате да копаете по-дълбоко и да научите други страхотни неща, които можете да правите с Jackson 2 - преминете към основния урок за Jackson.

2. Unmarshall да Array

Джаксън може лесно да десериализира до Java Array:

@Test public void givenJsonArray_whenDeserializingAsArray_thenCorrect() throws JsonParseException, JsonMappingException, IOException { ObjectMapper mapper = new ObjectMapper(); List 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 за събиране

Четенето на същия JSON масив в Java Collection е малко по-трудно - по подразбиране Jackson няма да може да получи пълната информация за общ тип и вместо това ще създаде колекция от свързани екземпляри на HashMap :

@Test public void givenJsonArray_whenDeserializingAsListWithNoTypeInfo_thenNotCorrect() throws JsonParseException, JsonMappingException, IOException { ObjectMapper mapper = new ObjectMapper(); List listOfDtos = Lists.newArrayList( new MyDto("a", 1, true), new MyDto("bc", 3, false)); String jsonArray = mapper.writeValueAsString(listOfDtos); List asList = mapper.readValue(jsonArray, List.class); assertThat((Object) asList.get(0), instanceOf(LinkedHashMap.class)); }

Има два начина да помогнете на Джаксън да разбере правилната информация за типа - можем да използваме TypeReference, предоставена от библиотеката за тази цел:

@Test public void givenJsonArray_whenDeserializingAsListWithTypeReferenceHelp_thenCorrect() throws JsonParseException, JsonMappingException, IOException { ObjectMapper mapper = new ObjectMapper(); List listOfDtos = Lists.newArrayList( new MyDto("a", 1, true), new MyDto("bc", 3, false)); String jsonArray = mapper.writeValueAsString(listOfDtos); List asList = mapper.readValue( jsonArray, new TypeReference
    
     () { }); assertThat(asList.get(0), instanceOf(MyDto.class)); }
    

Или можем да използваме претоварения метод readValue , който приема JavaType :

@Test publi void givenJsonArray_whenDeserializingAsListWithJavaTypeHelp_thenCorrect() throws JsonParseException, JsonMappingException, IOException { ObjectMapper mapper = new ObjectMapper(); List 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 asList = mapper.readValue(jsonArray, javaType); assertThat(asList.get(0), instanceOf(MyDto.class)); }

Последната бележка е, че класът MyDto трябва да има конструктор по подразбиране no-args - ако не го направи, Джаксън няма да може да го създаде :

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?)

4. Заключение

Картографирането на JSON масиви в java колекции е една от най-често срещаните задачи, за които се използва Jackson, и тези решения са жизненоважни за достигане до правилно, безопасно за типа картографиране .

Внедряването на всички тези примери и кодови фрагменти може да бъде намерено в нашия проект GitHub - това е проект, базиран на Maven, така че трябва да е лесно да се импортира и да се изпълнява както е.