#java #spring-boot
#java #весенняя загрузка
Вопрос:
Мы выполняем миграцию с версии Spring 5.0 на версию Spring Boot 2.4. Мой код контроллера выглядит следующим образом
@RequestMapping(value = "/getTreeNodesByFilter.action", method = RequestMethod.GET)
public @ResponseBody Map<String, ? extends Object> getTreeNodesByFilter(@RequestParam("type") String type,
@RequestParam("id") Long id, @RequestParam("pageNo") int pageNo, @RequestParam("pageSize") int pageSize,
@RequestParam("filterBy") String filterBy) {
Map<String, Object> responseMap = commonService.getTreeNodesByFilter(type, id, pageNo, pageSize, filterBy);
return ResponseUtil.getMap(responseMap);
}
Тело ответа представляет собой хэш-карту, как показано выше. Этот код отлично работает в обычном веб-приложении spring.
Тот же код, когда мы устали от SpringBoot, мы получаем следующую ошибку
java.lang.ClassCastException: class java.util.HashMap cannot be cast to class com.scriptless.web.security.exceptions.JsonError (java.util.HashMap is in module java.base of loader 'bootstrap'; com.scriptless.web.security.exceptions.JsonError is in unnamed module of loader org.springframework.boot.devtools.restart.classloader.RestartClassLoader @5f00ac7a)
Эта ошибка выдается из AbstractMessageConverterMethodProcessor.class из Spring-webmvc.jar во время выполнения кода
((HttpMessageConverter) converter).write(body, selectedMediaType, outputMessage);
Может кто-нибудь, пожалуйста, подсказать, что нужно сделать для решения этой проблемы?
Комментарии:
1. Кажется, есть ошибка безопасности, и она пытается сериализовать в неправильный класс. Попробуйте определить исходное исключение, а затем использовать для него обработку ошибок. Посмотрите здесь для обработки ошибок: baeldung.com/exception-handling-for-rest-with-spring
2. Вам нужно добавить полиморфный параметр проверки типов, чтобы разрешить подтипы HashMap, такие как allowIfSubType(«java.util.») в вашем ObjectMapper. Тогда, надеюсь, это должно сработать.
Ответ №1:
Попробуйте этот ObjectMapper,
public ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
.configure(MapperFeature.USE_GETTERS_AS_SETTERS, false);
SimpleModule module = new SimpleModule();
objectMapper.registerModule(module);
objectMapper.registerModule(new JavaTimeModule());
PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder()
.allowIfSubType("java.util.") //$NON-NLS-1$
.build();
objectMapper.setPolymorphicTypeValidator(ptv);
objectMapper.activateDefaultTyping(ptv, DefaultTyping.NON_FINAL);
return objectMapper;
}
Это позволило бы десериализовать все подтипы пакета java.util.*.