Пользовательский @ControllerAdvice в Spring для обработки исключений - PullRequest
0 голосов
/ 24 мая 2018

Я пытаюсь сопоставить исключения из моих контроллеров отдыха с ответами, которые имеют тело, и сделать это в центральном месте.

Я пробовал это:

@Order(Ordered.HIGHEST_PRECEDENCE)
@ControllerAdvice
public class RestErrorResponseExceptionHandler extends ResponseEntityExceptionHandler {
    @Override
    protected ResponseEntity<Object> handleExceptionInternal(
        Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request) {
        super.handleExceptionInternal(ex, body, headers, status, request);

        return ResponseEntity.status(status).body(Error.from(status));
    }
} 

Проблема в том, что обработчик никогда не запускается.

Если я определяю пользовательский метод с @ExceptionHandler в моих остальных контроллерахили расширить что-то, что имеет @ExceptionHandler, тогда все работает хорошо, но это приводит к некоторому плохому дизайну.

Насколько я понимаю, Spring сначала попытается найти в контроллере методы обработки исключений, а затем проверит зарегистрированные обработчики.

Я пытаюсь проверить поведение через WebMvcTest, и ответы, которые я получаю, не являются объектами Error, которые я ожидаю.

Есть что-то, что я пропускаю?

Ответы [ 3 ]

0 голосов
/ 24 мая 2018

Убедитесь, что 2 вещи работают, и ваш код будет работать.

  1. Ваш класс @ControllerAdvice доступен в пути для сканирования компонентов.
  2. Убедитесь, что методы в вашем @ControllerAdvice имеют структуру примерно так -
    @ExceptionHandler(value = { RequestProcessingException.class })
    public @ResponseBody ResponseEntity<ErrorMessageBO> hotelConfigServiceExceptionHandler(HttpServletRequest request, RequestProcessingException e) {
       logger.error("Exception with tracking Id: {}, dev message: {} and Message:", RequestContextKeeper.getContext().getRequestId(), e.getDeveloperMessage(),e);
       return new ResponseEntity<ErrorMessageBO>(new ErrorMessageBO(e.getErrorCode(), e.getMessage(),RequestContextKeeper.getContext().getRequestId(),e.getDeveloperMessage()), HttpStatus.OK);
    }
0 голосов
/ 24 мая 2018

Spring Framework предоставляет следующие способы, помогающие нам добиться надежной обработки исключений.

  1. На основе контроллера - Мы можем определить методы обработчика исключений в наших классах контроллеров.Все, что нам нужно, это аннотировать эти методы аннотацией @ExceptionHandler.Эта аннотация принимает класс Exception в качестве аргумента.Таким образом, если мы определили одно из них для класса Exception, то все исключения, сгенерированные нашим методом-обработчиком запросов, будут обработаны.Эти методы обработчика исключений аналогичны другим методам обработки запросов, и мы можем создать ответ об ошибке и ответить с другой страницей ошибки.Мы также можем отправить JSON-ответ об ошибке, который мы рассмотрим позже в нашем примере.Если определено несколько методов-обработчиков исключений, то используется метод-обработчик, ближайший к классу Exception.Например, если у нас есть два метода-обработчика, определенные для IOException и Exception, и наш метод-обработчик запроса выдает IOException, тогда будет выполнен метод обработчика для IOException.

  2. Global Exception Handler - Обработка исключений является сквозной задачей, это должно быть сделано для всех точек в нашем приложении.Мы уже рассмотрели Spring AOP, и именно поэтому Spring предоставляет аннотацию @ControllerAdvice, которую мы можем использовать с любым классом для определения нашего глобального обработчика исключений.Методы обработчика в Global Controller Advice аналогичны методам обработчика исключений на основе контроллера и используются, когда класс контроллера не может обработать исключение.

  3. HandlerExceptionResolver - для универсальногоисключения, в большинстве случаев мы обслуживаем статические страницы.Spring Framework предоставляет интерфейс HandlerExceptionResolver, который мы можем реализовать для создания глобального обработчика исключений.Причиной этого дополнительного способа определения глобального обработчика исключений является то, что Spring Framework также предоставляет классы реализации по умолчанию, которые мы можем определить в нашем файле конфигурации Spring Bean для получения преимуществ обработки исключений Spring Framework.SimpleMappingExceptionResolver является классом реализации по умолчанию, он позволяет нам настраивать исключенияMappings, где мы можем указать, какой ресурс использовать для конкретного исключения.Мы также можем переопределить его, чтобы создать собственный глобальный обработчик с изменениями, специфичными для нашего приложения, такими как регистрация сообщений об исключениях.

0 голосов
/ 24 мая 2018

ControllerAdvice - это конфигурация, которая должна быть зарегистрирована Spring.Вы должны переместить свой класс в пакет конфигурации или вы можете зарегистрировать его с помощью аннотации.

В моем случае я работаю с контроллером Advice, как этот:

@ControllerAdvice
public class GlobalControllerExceptionHandler {

    @ExceptionHandler(MyException.class) 
    public ResponseEntity<String> reponseMyException(Exception e) {
        return ResponseEntity.status(HttpStatus.FORBIDDEN).body("my message");
    }
}
...