在 Spring WebClient 中一次設定多個標頭
1. 簡介
在本教程中,我們將了解如何在 Spring WebClient
中一次設定多個標頭。
WebClient
是 Spring WebFlux 的一個類,簡單來說,它支援同步和非同步 HTTP 請求。我們首先了解WebClient
如何處理標題,然後透過程式碼範例探索一次設定多個標題的不同方法。
2. WebClient
如何處理標頭
一般來說,HTTP 請求中的標頭充當元資料。它們攜帶諸如身份驗證詳細資訊、內容類型、版本等資訊。
在WebClient
中, HttpHeaders
類別管理標頭。它是一個專門設計用於表示請求和回應標頭的 Spring 框架類別。它實作了MultiValueMap
<String, String>,
允許單一標頭鍵具有多個值。
這為需要多個值的標頭(例如Accept
)提供了靈活性。
3. 在WebClient
中設定多個 Header
有多種方法可以向請求新增標頭。根據用例,我們可以為單一請求設定標頭,為整個WebClient
實例定義全域標頭,或動態修改它們。
讓我們透過程式碼範例來探索這些方法。
3.1.為單一請求設定標頭
當標頭特定於單一請求並且因端點而異時,直接的方法是在請求上直接設定它們。
在下面的範例中,我們建立一個簡單的測試,其中我們實例化WebClient
,向請求添加兩個標頭,並斷言請求是使用這些標頭發送的。我們也使用 okhttp3 庫中的MockWebServer
來模擬伺服器回應並驗證我們的WebClient
的行為:
@Test
public void givenRequestWithHeaders_whenSendingRequest_thenAssertHeadersAreSent() throws Exception {
mockWebServer.enqueue(new MockResponse().setResponseCode(HttpStatus.OK.value()));
WebClient client = WebClient.builder()
.baseUrl(mockWebServer.url("/").toString())
.build();
ResponseEntity<Void> response = client.get()
.headers(headers -> {
headers.put("X-Request-Id", Collections.singletonList(RANDOM_UUID));
headers.put("Custom-Header", Collections.singletonList("CustomValue"));
})
.retrieve()
.toBodilessEntity()
.block();
assertNotNull(response);
assertEquals(HttpStatusCode.valueOf(HttpStatus.OK.value()), response.getStatusCode());
RecordedRequest recordedRequest = mockWebServer.takeRequest();
assertEquals(RANDOM_UUID, recordedRequest.getHeader("X-Request-Id"));
assertEquals("CustomValue", recordedRequest.getHeader("Custom-Header"));
}
此範例使用WebClient
類別中的headers(Consumer<HttpHeaders> headersConsumer)
方法。
正如我們之前提到的, WebClient
依賴HttpHeaders,
在此上下文中,HttpHeaders 是使用Consumer
功能介面進行配置的。此設定允許我們透過傳遞對HttpHeaders
實例進行操作的 lambda 來修改請求標頭。
3.2.全域設定預設標頭
在其他場景中,我們可能需要定義全域標題。這些標頭是在全域層級配置的,並且它們會自動添加到使用此客戶端實例發出的每個請求中。這種配置有助於我們保持一致性並減少重複。
我們總是可以用請求特定的標頭覆蓋全域標頭,因為它們僅充當基線。與以前的方法唯一的區別是我們在構建WebClient
時添加它們:
WebClient client = WebClient.builder()
.baseUrl(mockWebServer.url("/").toString())
.defaultHeaders(headers -> {
headers.put("X-Request-Id", Collections.singletonList(RANDOM_UUID));
headers.put("Custom-Header", Collections.singletonList("CustomValue"));
})
.build();
3.3.使用ExchangeFilterFunction
動態修改標頭
在某些情況下,我們可能希望在運行時動態設定或修改標題。對於這種情況,我們可以使用ExchangeFilterFunction
類別:
ExchangeFilterFunction dynamicHeadersFilter = (request, next) -> next.exchange(ClientRequest.from(request)
.headers(headers -> {
headers.put("X-Request-Id", Collections.singletonList(RANDOM_UUID));
headers.put("Custom-Header", Collections.singletonList("CustomValue"));
})
.build());
建構ExchangeFilterFunction
實例後,我們在實例化期間將其註冊到WebClient
:
WebClient client = WebClient.builder()
.baseUrl(mockWebServer.url("/").toString())
.filter(dynamicHeadersFilter)
.build();
另外值得注意的是,我們可以為單一WebClient
堆疊多個過濾函數實例。
4. 結論
在本文中,我們探討了 Spring WebClient
如何處理標頭,並了解了設定多個標頭的幾種方法。無論是針對單一請求、全域所有請求還是在運行時動態地管理標頭, WebClient
提供了一種直接靈活的方法來一致、乾淨地管理標頭。
與往常一樣,完整的程式碼範例可在 GitHub 上找到。