Джексон отображает свойства по имени !
Некоторые советы Java Guy помогут решить проблему путем изменения имени вложенного ArrayList от university
до data
(аналогично соответствующему массиву в JSON).
java.lang.NullPointerException
(NPE) выбрасывается при попытке получить список из объекта root.
Проблема: что случилось?
1. Допустимый шаблон считывателя:
Вы отключили DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
Это говорит Джексону о десериализации допустимого JSON в объект, даже если некоторые из его содержимого не может быть отображено.
Без отключения этого (настройка по умолчанию) Джексон бы сгенерировал исключение (JsonMappingException
) здесь, так как JSON свойство data
не может быть сопоставлено ни с одним из свойств класса UniversityList
.
2. Свойства не были сопоставлены, все остаются null
:
Объект list
создан (с использованием конструктора default / no-args ). Но поскольку его свойство ArrayList university
не было ни инициализировано, ни установлено (отображено) Джексоном, оно остается null
.
3. NPE, брошенный при доступе:
Как только ваш для l oop попытается получить доступ к свойству через list.getUniversity()
, NPE выбрасывается.
Предотвращение NPE: Защитное кодирование
Всегда следите за тем, чтобы используемый вами объект (ссылка) был не нулевым , здесь:
if (list != null && list.getUniversity() != null) {
// now below for loop is safe (no NPE)
for (University u : list.getUniversity()) {
// do something with u
}
}
Кроме того, обычно это хорошая практика инициализировать списки, даже если они пусты. Например, в вашем классе UniversityList
объявите:
List<University> university = new ArrayList<>();
Обращайтесь с осторожностью: особенности Джексона
Хотя используемый DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
будет действовать как Джокер здесь, позволяя Джексону читать JSON, даже если отображение не подходит, вам следует обратить особое внимание и проверить возвращаемые значения . См. Аналогичный вопрос: { ссылка }
Определить сопоставление Джексона
Либо использовать сопоставление Джексона по умолчанию по имени : Java Имя свойства объекта должно быть то же как в JSON. Или используйте аннотации @JsonProperty
, чтобы определить JSON имя , если оно отклоняется от Java Имя объекта.
В вашем случае это будет:
@JsonProperty("data")
List<University> university = new ArrayList<>();
Настройка Джексона
Джексон предлагает множество аннотаций, позволяющих выполнить настройку. См. Статья Баэльдуна .
Таким образом, вы можете заменить глобально отключенного DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
на аннотацию класса c:
@JsonIgnoreProperties(ignoreUnknown = true)
public class UniversityList {
// body removed
}