Пользовательский HandlerMethodArgumentResolver отсутствует основном проекте, но в библиотеке, импортированной основным приложением. Сканирование Pom и компонентов в порядке, поскольку другие bean-компоненты и конфигурации обрабатываются без проблем.
Все работает нормально, если запустить его на JVM, но скомпилировать его как собственное приложение с GraalVM - это вызывает у меня проблемы, потому что при запуске приложения пользовательский преобразователь аргументов не будет учитываться, а введенный пользовательский объект имеет значение null во время выполнения.
Вот это код.
Код: Выделить всё
public class HeaderMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterType().equals(MyHeader.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
MyHeader header = MyHeaderExtractor.generateFrom(webRequest);
// Makes Validated annotation working on my custom argument
if (parameter.hasParameterAnnotation(Validated.class) || parameter.hasParameterAnnotation(Valid.class)) {
// Validate header
WebDataBinder binder = binderFactory.createBinder(webRequest, header, parameter.getParameterName());
validateIfApplicable(binder, parameter);
if (binder.getBindingResult().hasErrors()) {
throw new MethodArgumentNotValidException(parameter, binder.getBindingResult());
}
}
return header;
}
/**
* Validate the model attribute if applicable.
*
The default implementation checks for {@code @jakarta.validation.Valid},
* Spring's {@link org.springframework.validation.annotation.Validated},
* and custom annotations whose name starts with "Valid".
* @param binder the DataBinder to be used
* @param parameter the method parameter declaration
* @see WebDataBinder#validate(Object...)
* @see SmartValidator#validate(Object, Errors, Object...)
*/
protected void validateIfApplicable(WebDataBinder binder, MethodParameter parameter) {
for (Annotation ann : parameter.getParameterAnnotations()) {
Object[] validationHints = ValidationAnnotationUtils.determineValidationHints(ann);
if (validationHints != null) {
binder.validate(validationHints);
break;
}
}
}
}
Код: Выделить всё
@EnableWebMvc // Tried with and without EnableWebMvc
@Configuration(proxyBeanMethods = false)
public class HeaderMethodArgumentResolverConfiguration implements WebMvcConfigurer {
@Override
public void addArgumentResolvers(List resolvers) {
// tried this
resolvers.add(new HeaderMethodArgumentResolver());
// and also this when created as a Bean
resolvers.add(headerMethodArgumentResolver());
}
@Bean // Tried with and without this method
public HeaderMethodArgumentResolver headerMethodArgumentResolver() {
return new HeaderMethodArgumentResolver();
}
}
Код: Выделить всё
@RestController
@RequestMapping("/api/my-resource")
@Slf4j
public class MyController {
@PostMapping("/example")
public MyResponseObject doSomething(
@Validated({HeaderAsIWant.class}) MyHeader myHeader,
@Validated @RequestBody MyRequestObject request) {
}
}
Большое спасибо всем, кто ответит ответ.
ПРИМЕЧАНИЕ 1. Я проверил вызов /actuator/beans и уверен, что экземпляр компонента был создан правильно. Похоже, проблема в том, что Spring не вызывает преобразователь метода при поступлении запроса.
ПРИМЕЧАНИЕ 2. Перемещение настраиваемого преобразователя аргументов из библиотеки в основной проект решает проблему. проблема. Хотя для меня это не решение, поскольку мне нужно использовать этот преобразователь аргументов в нескольких микросервисах, возможно, без его копирования.
Подробнее здесь: https://stackoverflow.com/questions/771 ... ot-working
Мобильная версия