1. 概述
憑藉 Spring Boot 2 和新的非阻塞服務器 Netty,我們不再依賴 Servlet 上下文 API,因此我們來探討如何使用新的棧來表達不同類型的 HTTP 狀態碼。
2. 語義響應狀態
遵循標準 RESTful 實踐,我們需要充分利用完整的 HTTP 狀態碼來準確表達 API 的語義。
2.1. 默認返回狀態
當然,如果一切順利,默認響應狀態是 200 (OK):
@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() {
//
}要了解更多關於如何操作的方法,請務必查看 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,我們可以以功能的方式定義端點,從而可以程序matically 地更改默認的 HTTP 狀態碼:
@Bean
public RouterFunction<ServerResponse> notFound() {
return RouterFunctions
.route(GET("/statuses/not-found"),
request -> ServerResponse.notFound().build());
}3. 結論
在實施 HTTP API 時,框架提供了多種選項,用於智能處理我們向客户端暴露的狀態碼。
本文應該是一個不錯的起點,可以幫助您探索這些選項,並瞭解如何構建具有表達力、友好的 API,同時遵循清晰的 RESTful 語義。