У меня есть приложение, которое использует Spring Boot для обеспечения возможности REST. У меня возникла проблема с десериализацией ответа POST в POJO. Исключение составляет следующее:
org.springframework.http.converter.HttpMessageConversionException: Type definition error: [collection type; class uci.BoundedList, contains [simple type, class java.lang.Object]]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `uci.BoundedList` (no Creators, like default construct, exist): no default no-arguments constructor found
Тип BoundedList
является частью API, созданного из схемы XML с помощью XJC. Я не могу контролировать, как генерируется этот класс. Оказывается, это подкласс java.util.ArrayList
и имеет только один определенный конструктор:
public BoundedList(int minOccurs, int maxOccurs) {
super();
this.minOccurs = minOccurs;
this.maxOccurs = maxOccurs;
}
Он не определяет конструктор без аргументов, на что, похоже, жалуется исключение.
Поскольку я не могу изменить этот класс, и он является неотъемлемой частью используемого мной API, что я могу сделать, чтобы обойти эту проблему? Могу ли я предоставить какой-то настраиваемый класс/интерфейс, который удовлетворит привязку данных Джексона? Какое-то другое возможное решение?
ОБНОВЛЕНИЕ:
Я попробовал ряд предложений, основанных на ответах, представленных ниже. Ни один из них не работает. Я изучаю подход "mix-in" и, признаюсь, не совсем понимаю, как он должен работать. Многие статьи, которые я читал, написаны просто, но все же это кажется небольшой «черной магией».
В любом случае, ниже приведены фрагменты того, что я пытался сделать на основе того, что я прочитал:
Класс «смешанный»:
public abstract class BoundedListMixin {
@JsonCreator
public BoundedListMixin(@JsonProperty("minOccurs") int minOccurs,
@JsonProperty("maxOccurs") int maxOccurs) {}
}
Что было добавлено в существующий класс конфигурации:
@Configuration
@EnableAsync
@EnableScheduling
@ComponentScan("<package>")
public class ServiceConfigurer {
@Bean
@Primary
public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
ObjectMapper mapper = builder.createXmlMapper(false).build();
mapper.addMixIn(BoundedList.class, BoundedListMixin.class);
return mapper;
}
}
Я могу подтвердить, что метод objectMapper()
в классе конфигурации вызывается через отладчик.
Эта ссылка (https://dzone.com/articles/jackson-mixin-to-the-rescue) вводит еще одну грань, но, увы, и она не работает.
ОБНОВЛЕНИЕ:
Я заменил метод objectMapper()
в ServiceConfigurer
(выше) следующим:
@Bean
public Jackson2ObjectMapperBuilderCustomizer objectMapperCustomizer() {
return new Jackson2ObjectMapperBuilderCustomizer() {
@Override
public void customize(Jackson2ObjectMapperBuilder builder) {
builder.mixIn(BoundedList.class, BoundedListMixin.class);
}
};
}
Я ВСЕ ЕЩЕ получаю ту же проблему. Проблема должна быть связана с каким-то другим вопросом.
ПРИМЕЧАНИЕ:
Я также должен уточнить, что эта проблема проявляется, когда я сделал вызов GET
. У меня есть простая конечная точка REST, которая просто запрашивает у службы возврат POJO. Как ни странно, если я отправляю запрос из браузера, объект возвращается как JSON и отображается. Но когда он вызывается из кода, я получаю исключение выше.
ПОЛУЧИТЬ вызов:
RequestStatus statusMsg = template.getForObject("http://localhost:8080/rst/missionPlanning/data", RequestStatus.class);