Рубрики
Без рубрики

Spring ResponseStatusException

Узнайте, как применять коды состояния к ответам HTTP весной с помощью ResponseStatusException.

Автор оригинала: baeldung.

1. Обзор

В этом кратком руководстве мы обсудим новый класс ResponseStatusException , представленный весной 5. Этот класс поддерживает применение кодов состояния HTTP к ответам HTTP.

Приложение RESTful может сообщить об успешном или неудачном выполнении HTTP-запроса, вернув правильный код состояния в ответе клиенту . Проще говоря, соответствующий код состояния может помочь клиенту определить проблемы, которые могли возникнуть во время обработки запроса приложением.

2. Статус Ответа

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

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

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

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

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

3. 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, аргументы конструктора:

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

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

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

3.1. Преимущества исключения ResponseStatusException

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

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

4. Примеры

4.1. Сгенерировать исключение ResponseStatusException

Теперь давайте рассмотрим пример, который генерирует исключение ResponseStatusException :

@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);
    }
}

Spring Boot предоставляет сопоставление по умолчанию /error , возвращающее ответ JSON со статусом HTTP.

Вот как выглядит ответ:

$ curl -i -s -X GET http://localhost:8081/actor/8
HTTP/1.1 404
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Sat, 26 Dec 2020 19:38:09 GMT

{
    "timestamp": "2020-12-26T19:38:09.426+00:00",
    "status": 404,
    "error": "Not Found",
    "message": "",
    "path": "/actor/8"
}

Начиная с версии 2.3, Spring Boot не содержит сообщения об ошибке на странице ошибок по умолчанию. Причина заключается в снижении риска утечки информации клиенту

Чтобы изменить поведение по умолчанию, мы можем использовать свойство server.error.include-message .

Давайте установим его в всегда и посмотрим, что произойдет:

$ curl -i -s -X GET http://localhost:8081/actor/8
HTTP/1.1 404
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Sat, 26 Dec 2020 19:39:11 GMT

{
    "timestamp": "2020-12-26T19:39:11.426+00:00",
    "status": 404,
    "error": "Not Found",
    "message": "Actor Not Found",
    "path": "/actor/8"
}

Как мы видим, на этот раз ответ содержит сообщение об ошибке “Актер не найден” .

4.2. Другой Код Состояния – Тот Же Тип Исключения

Теперь давайте посмотрим, как другой код состояния устанавливается в HTTP-ответ при возникновении исключения того же типа:

@PutMapping("/actor/{id}/{name}")
public String updateActorName(
  @PathVariable("id") int id, 
  @PathVariable("name") String name) {
 
    try {
        return actorService.updateActor(id, name);
    } catch (ActorNotFoundException ex) {
        throw new ResponseStatusException(
          HttpStatus.BAD_REQUEST, "Provide correct Actor Id", ex);
    }
}

Вот как выглядит ответ:

$ curl -i -s -X PUT http://localhost:8081/actor/8/BradPitt
HTTP/1.1 400
...
{
    "timestamp": "2018-02-01T04:28:32.917+0000",
    "status": 400,
    "error": "Bad Request",
    "message": "Provide correct Actor Id",
    "path": "/actor/8/BradPitt"
}

5. Заключение

В этом кратком руководстве мы обсудили, как создать ResponseStatusException в нашей программе.

Мы также подчеркнули, что программно это лучший способ установить коды состояния HTTP в HTTP-ответе, чем @ResponseStatus аннотации.

Как всегда, полный исходный код доступен на GitHub .