1. 概述
使用 HTTP 響應的狀態碼來確定應用程序應如何處理給定的響應,通常很有幫助。
在本教程中,我們將學習如何使用 WebFlux 的 <em >WebClient</em >> 訪問並獲取來自 REST 請求的狀態碼和響應正文。
<em >WebClient</em >> 引入於 Spring 5 中,可用於異步 I/O 調用 RESTful 服務。
2. 使用場景
當向其他服務發出 RESTful 調用時,應用程序通常會使用返回的 狀態碼 來觸發不同的功能。 典型的使用場景包括優雅的錯誤處理、重試請求以及確定用户錯誤。
因此,在發出 REST 調用時,僅僅獲得響應碼通常是不夠的。 有時我們還需要響應體。
在以下示例中,我們將看到如何從 REST 客户端 WebClient 中解析響應體。 我們會將行為與返回的狀態碼關聯起來,並利用 WebClient 提供的兩個狀態碼提取方法,onStatus 和 ExchangeFilterFunction。
3. 使用 <em onStatus</em>
使用 `onStatus` 是一個內置機制,可用於處理 `` 響應。 這允許我們根據特定響應(例如 400、500、503 等)或狀態類別(例如 4XX 和 5XX 等)應用精細功能。
WebClient
.builder()
.build()
.post()
.uri("/some-resource")
.retrieve()
.onStatus(
HttpStatus.INTERNAL_SERVER_ERROR::equals,
response -> response.bodyToMono(String.class).map(Exception::new))onStatus 方法需要兩個參數。第一個參數是一個謂詞,它接受一個狀態碼。第二個參數的執行基於第一個參數的輸出。第二個參數將響應映射為 Mono 或 Exception。
在這種情況下,如果看到 INTERNAL_SERVER_ERROR(即 500),我們將使用 bodyToMono 獲取 body,然後將它映射為新的 Exception。
我們可以鏈接 onStatus 調用,以便為不同的狀態條件提供功能:
Mono<String> response = WebClient
.builder()
.build()
.post()
.uri("some-resource")
.retrieve()
.onStatus(
HttpStatus.INTERNAL_SERVER_ERROR::equals,
response -> response.bodyToMono(String.class).map(CustomServerErrorException::new))
.onStatus(
HttpStatus.BAD_REQUEST::equals,
response -> response.bodyToMono(String.class).map(CustomBadRequestException::new))
...
.bodyToMono(String.class);
// do something with response現在, 調用將映射到我們自定義的異常。我們為這兩個錯誤狀態分別定義了異常類型。 方法允許我們選擇任何類型。
4. 使用 <em >ExchangeFilterFunction</em >
<em >ExchangeFilterFunction</em >> 是一種處理特定狀態碼和獲取響應體的方法。 與 <em >onStatus</em >> 相比,ExchangeFilterFunction 更加靈活,可以基於任何布爾表達式應用過濾功能。
我們可以利用 <em >ExchangeFilterFunction</em >> 的靈活性來覆蓋 <em >onStatus</em >> 函數所涵蓋的相同類別。
首先,我們將定義一個方法來處理基於狀態碼的返回邏輯,該方法接收一個 <em >ClientResponse</em >> 對象:<em >ClientResponse</em >> 對象。
private static Mono<ClientResponse> exchangeFilterResponseProcessor(ClientResponse response) {
HttpStatusCode status = response.statusCode();
if (HttpStatus.INTERNAL_SERVER_ERROR.equals(status)) {
return response.bodyToMono(String.class)
.flatMap(body -> Mono.error(new CustomServerErrorException(body)));
}
if (HttpStatus.BAD_REQUEST.equals(status)) {
return response.bodyToMono(String.class)
.flatMap(body -> Mono.error(new CustomBadRequestException(body)));
}
return Mono.just(response);
}接下來,我們將定義過濾器並使用方法引用指向我們的處理程序:
ExchangeFilterFunction errorResponseFilter = ExchangeFilterFunction
.ofResponseProcessor(WebClientStatusCodeHandler::exchangeFilterResponseProcessor);類似於 onStatus 調用,我們正在將錯誤映射到我們的 Exception 類型。但是,使用 Mono.error 會將此 Exception 包裝在 ReactiveException 中。在處理錯誤時,應注意此嵌套關係。
現在,我們將 應用此方法到 WebClient 實例以達到與 onStatus 鏈式調用相同的效果:
Mono<String> response = WebClient
.builder()
.filter(errorResponseFilter)
.build()
.post()
.uri("some-resource")
.retrieve()
.bodyToMono(String.class);
// do something with response5. 結論
本文介紹了根據 HTTP 狀態頭獲取響應體的一些方法。通過狀態碼,onStatus 方法允許我們插入特定的功能。此外,我們還可以使用 filter 方法來插入通用的方法,用於處理所有響應的後處理。