Метод @ControllerAdvice не выполняется, и он выполняет базовый класс ответа

#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, и это сработало.