Перейти к основному содержимому

Как вернуть 404 с помощью Spring WebFlux

· 3 мин. чтения

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() {
//
}

Чтобы узнать больше о том, как это сделать, обязательно ознакомьтесь со статьей «Обработка ошибок» на ForEach .

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 .