#java #spring-boot
Вопрос:
Я написал свой класс ProductController для весенней загрузки с помощью метода ProductDetail и метода handleMethodArgumentNotValid . Метод handleMethodArgumentNotValid снабжен аннотацией @ExceptionHandler(MethodArgumentNotValid.class). Это сработало совершенно нормально. После этого я удалил метод handleMethodArgumentNotValid из класса контроллера, так как я хотел бы использовать @ControllerAdvice. Но он выполняет класс BaseException проекта. Он не выполняет метод @ControllerAdvice.
Here is my Controller class.
@PostMapping("/productDetail")
public void productDetail(@Valid @RequestBody ProductDetail productDetail) {
System.out.println("I am in Controller ProductDetail ....");
try {
iOrderService.updateProductDetail(productDetail);
} catch (Exception e) {
//Executes Base Exception class information here
...
}
}
Here is my ControllerAdvice .
@ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
@Override
@ResponseStatus(HttpStatus.UNPROCESSABLE_ENTITY)
protected ResponseEntity<Object> handleMethodArgumentNotValid(
MethodArgumentNotValidException ex,
HttpHeaders headers,
HttpStatus status,
WebRequest request
) {
same code that I had in handleMethodArgumentNotValid method of ProductController class here
ErrorResponse errorResponse = new ErrorResponse(
HttpStatus.UNPROCESSABLE_ENTITY.value(),
"Validation error. Check 'errors' field for details."
);
for (FieldError fieldError : ex.getBindingResult().getFieldErrors()) {
errorResponse.addValidationError(fieldError.getField(),
fieldError.getDefaultMessage());
}
return ResponseEntity.unprocessableEntity().body(errorResponse);
}
Как я могу обработать исключение MethodArgumentNotValidException, чтобы оно не выполняло класс BaseException?
Ответ №1:
Ваш глобальный обработчик исключений может обрабатывать только неучтенные исключения. Поэтому , если вы хотите, чтобы он обрабатывал что-либо брошенное iOrderService.updateProductDetail(productDetail);
, вам нужно будет удалить попытку/улов.
Я подозреваю, что ваш тестовый ввод на productDetail()
самом деле не вызывает MethodArgumentNotValidException
. Либо это, либо ваш глобальный обработчик исключений не включен в сканирование компонентов. Я бы рекомендовал добавить метод «catchAll» в ваш глобальный обработчик исключений для целей тестирования. Просто чтобы посмотреть, улавливает ли он вообще какие-либо исключения.
@ExceptionHandler(Exception.class)
protected ResponseEntity<ExceptionEnvelope> catchAll(Exception exception, WebRequest request) {
return buildResponse(HttpStatus.INTERNAL_SERVER_ERROR, exception, request);
}
Установите там точку останова и просто посмотрите, сможете ли вы ее достичь. У меня и раньше были подобные проблемы, и в итоге мои предположения оказались неверными относительно того, какие исключения возникают в разных обстоятельствах. Перехват всех подобных исключений позволит вам проверить, правильно ли подключен обработчик GlobalExceptionHandler, а также сообщит вам, какое исключение на самом деле создается.
Комментарии:
1. Да, вы правы, мне нужно указать catchAll в GlobalExceptionHandler и удалить блок try/catch.
2. Сегодня я добавил заметку в GlobalExceptionHandler, но она не прошла через нее. Он каким-то образом вызывает класс BaseResponse с кодом ошибки : «НЕОБРАБОТАННАЯ СУЩНОСТЬ» и сообщением об ошибке: «Ошибка проверки».
Ответ №2:
Я изменил аннотацию RestController на аннотацию @Controller в классе контроллера и аннотированный метод с помощью @ResponseBody, и это сработало.