Spring ResponseStatusException

Spring ResponseStatusException

1. обзор

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

Приложение RESTful может сообщить об успешном или неудачном выполнении HTTP-запросаreturning the right status code in the response to the client. Проще говоря, соответствующий код состояния может помочь клиенту определить проблемы, которые могли возникнуть, когда приложение обрабатывало запрос.

2. ResponseStatusс

Прежде чем мы углубимся в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 будут генерировать одно и то же сообщение об ошибке и код состояния в ответе.

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,:

  • status - статус HTTP, установленный на HTTP-ответ

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

  • причина -Throwable причинаResponseStatusException

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

Один из этих обработчиков,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:8080/actor/8
HTTP/1.1 404
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Sun, 28 Jan 2018 19:48:10 GMT

{
    "timestamp": "2018-01-28T19:48:10.471+0000",
    "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:8080/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.

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