Обработка ошибок с помощью класса ResponseStatusException - PullRequest
0 голосов
/ 08 января 2019

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

Какие-нибудь советы, как это сделать правильно?

1 Ответ

0 голосов
/ 09 марта 2019

Прежде чем мы углубимся в ResponseStatusException, давайте быстро взглянем на аннотацию @ ResponseStatus . Эта аннотация была введена в Spring 3 для применения кода статуса HTTP к ответу HTTP.

Мы можем использовать аннотацию @ResponseStatus, чтобы установить статус и причину в нашем HTTP-ответе:

@ResponseStatus(code = HttpStatus.NOT_FOUND, reason = "Actor Not Found")
public class ActorNotFoundException extends Exception {
    // ...
}

Если это исключение выдается при обработке запроса HTTP, то в ответ будет включен статус HTTP, указанный в этой аннотации.

Один недостаток подхода @ResponseStatus заключается в том, что он создает тесную связь с исключением. В нашем примере все исключения типа ActorNotFoundException будут генерировать одно и то же сообщение об ошибке и код состояния в ответе.

ResponseStatusException

ResponseStatusException является программной альтернативой @ResponseStatus и является базовым классом для исключений, используемых для применения кода состояния к HTTP-ответу. Это исключение RuntimeException, поэтому его не нужно явно добавлять в сигнатуру метода.

Spring предоставляет 3 конструктора для генерации ResponseStatusException:

ResponseStatusException(HttpStatus status)
ResponseStatusException(HttpStatus status, java.lang.String reason)
ResponseStatusException(
  HttpStatus status, 
  java.lang.String reason, 
  java.lang.Throwable cause
)

ResponseStatusException, аргументы конструктора:

  • status - статус HTTP установлен на HTTP-ответ
  • причина - сообщение, объясняющее исключение, установленное для ответа HTTP
  • причина - одноразовая причина ResponseStatusException

Примечание: в Spring HandlerExceptionResolver перехватывает и обрабатывает любое исключение, вызванное и не обработанное контроллером.

Один из этих обработчиков, ResponseStatusExceptionResolver, ищет любые исключения ResponseStatusException или uncaught, аннотированные @ResponseStatus, а затем извлекает код и причину состояния HTTP и включает их в ответ HTTP.

Преимущества ResponseStatusException

Использование ResponseStatusException имеет несколько преимуществ:

  • Во-первых, исключения одного и того же типа могут обрабатываться отдельно, а в ответе могут быть установлены разные коды состояния, уменьшая жесткую связь
  • Во-вторых, избегает создания ненужных дополнительных классов исключений
  • Наконец, он обеспечивает больший контроль над обработкой исключений, поскольку исключения могут создаваться программно

Spring 5 представил класс ResponseStatusException. Мы можем создать его экземпляр, предоставив HttpStatus и, возможно, причину и причину:

@GetMapping("/actor/{id}")
public String getActorName(@PathVariable("id") int id) {
    try {
        return actorService.getActor(id);
    } catch (ActorNotFoundException ex) {
        throw new ResponseStatusException(
        HttpStatus.NOT_FOUND, "Actor Not Found", ex);
    }
}

Каковы преимущества использования ResponseStatusException?

  • Отлично подходит для создания прототипов: мы можем довольно быстро реализовать базовое решение
  • Один тип, несколько кодов состояния. Один тип исключения может привести к нескольким различным ответам. Это уменьшает жесткую связь по сравнению с @ ExceptionHandler
  • Нам не нужно создавать столько пользовательских классов исключений
  • Больше контроля над обработкой исключений, поскольку исключения могут создаваться программно

А как насчет компромиссов?

  • Единого способа обработки исключений не существует: реализовать некоторые соглашения для всего приложения труднее, чем @ControllerAdvice, который обеспечивает глобальный подход
  • Дублирование кода: мы можем оказаться копирующими код на нескольких контроллерах

Следует также отметить, что в одном приложении можно комбинировать разные подходы.

Например, мы можем реализовать @ControllerAdvice глобально, а также ResponseStatusExceptions локально. Однако мы должны быть осторожны: если одно и то же исключение может быть обработано несколькими способами, мы можем заметить некоторое неожиданное поведение. Возможное соглашение - обрабатывать одно конкретное исключение всегда одним способом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...