«1. Обзор

Благодаря Spring Boot 2 и новому неблокирующему серверу Netty у нас больше нет контекстного API сервлета, поэтому давайте обсудим, как мы можем выражать различные типы кодов состояния HTTP, используя новый стек. .

2. Статус семантического ответа

Следуя стандартной практике RESTful, нам, естественно, необходимо использовать весь диапазон кодов состояния HTTP для правильного выражения семантики API.

2.1. Статус возврата по умолчанию

Конечно, когда все идет хорошо, статус ответа по умолчанию — 200 (ОК):

@GetMapping(
  value = "/ok",
  produces = MediaType.APPLICATION_JSON_UTF8_VALUE
)
public Flux<String> ok() {
    return Flux.just("ok");
}

2.2. Использование аннотаций

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

@GetMapping(
  value = "/no-content",
  produces = MediaType.APPLICATION_JSON_UTF8_VALUE
)
@ResponseStatus(HttpStatus.NO_CONTENT)
public Flux<String> noContent() {
    return Flux.empty();
}

2.3. Программное изменение статуса

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

Мы можем добиться этого, напрямую внедрив ServerHttpResponse в наш метод:

@GetMapping(
  value = "/accepted",
  produces = MediaType.APPLICATION_JSON_UTF8_VALUE
)
public Flux<String> accepted(ServerHttpResponse response) {
    response.setStatusCode(HttpStatus.ACCEPTED);
    return Flux.just("accepted");
}

Теперь мы можем выбрать, какой код состояния HTTP мы будем возвращать прямо в реализации.

2.4. Генерация исключения

Каждый раз, когда мы выбрасываем исключение, статус возврата HTTP по умолчанию опускается, и Spring пытается найти обработчик исключений для его обработки:

@GetMapping(
  value = "/bad-request"
)
public Mono<String> badRequest() {
    return Mono.error(new IllegalArgumentException());
}
@ResponseStatus(
  value = HttpStatus.BAD_REQUEST,
  reason = "Illegal arguments")
@ExceptionHandler(IllegalArgumentException.class)
public void illegalArgumentHandler() {
    // 
}

Чтобы узнать больше о том, как это сделать, обязательно проверьте -out the Error Handling article на Baeldung.

2.5. С ResponseEntity

Давайте теперь кратко рассмотрим интересную альтернативу — класс ResponseEntity.

Это позволяет нам выбирать, какой HTTP-статус мы хотим вернуть, а также настраивать наши ответы гораздо дальше, используя очень полезный гибкий API:

@GetMapping(
  value = "/unauthorized"
)
public ResponseEntity<Mono<String>> unathorized() {
    return ResponseEntity
      .status(HttpStatus.UNAUTHORIZED)
      .header("X-Reason", "user-invalid")
      .body(Mono.just("unauthorized"));
}

2.6. С функциональными конечными точками

В Spring 5 мы можем определять конечные точки функциональным способом, поэтому мы также можем изменить статус HTTP по умолчанию программно:

@Bean
public RouterFunction<ServerResponse> notFound() {
    return RouterFunctions
      .route(GET("/statuses/not-found"),
         request -> ServerResponse.notFound().build());
}

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

При реализации HTTP API, фреймворк предоставляет ряд опций для разумной обработки кодов состояния, которые мы отправляем обратно клиенту.

Эта статья должна стать хорошей отправной точкой для их изучения и понимания того, как можно развернуть выразительный, дружественный API с чистой семантикой RESTful.

Конечно, полные примеры кода, используемые в этом руководстве, доступны на Github.