Spring 6.1 新功能:RestClient

工程 | Arjen Poutsma | 2023 年 7 月 13 日 | ...

Spring Framework 6.1 M2 引入了新的同步 HTTP 客戶端 RestClient。顧名思義,RestClient 提供了 WebClient 的流暢 API 以及 RestTemplate 的基礎架構。

十四年前,當 Spring Framework 3.0 引入 RestTemplate 時,我們很快發現,在類似範本的類別中公開 HTTP 的所有功能會導致過多的方法重載。因此,在 Spring Framework 5 中,我們為反應式 WebClient 使用了流暢的 API。透過 RestClient,我們引入了一個 HTTP 客戶端,它提供類似於 WebClient 的 API,並使用 RestTemplate 的訊息轉換器、請求工廠、攔截器和其他底層組件。

建立 RestClient

您可以使用靜態 create 方法之一來建立 RestClient。您也可以使用 RestClient::builder 來取得具有更多選項的建構器,例如指定要使用的 HTTP 客戶端、設定預設 URL、路徑變數和標頭,或註冊攔截器和初始化器。

使用 RestClient::create(RestTemplate),您可以使用現有的 RestTemplate 的配置來初始化 RestClient

Retrieve

讓我們建立一個 RestClient,使用它來設定基本的 GET 請求,並使用 retrieve 以字串形式檢索網站的內容

RestClient restClient = RestClient.create();

String result = restClient.get()
  .uri("https://example.com")
  .retrieve()
  .body(String.class);
System.out.println(result);

如果您對回應狀態碼和標頭感興趣,而不僅僅是內容,則可以使用 toEntity 來取得 ResponseEntity

ResponseEntity<String> result = restClient.get()
  .uri("https://example.com")
  .retrieve()
  .toEntity(String.class);

System.out.println("Response status: " + result.getStatusCode());
System.out.println("Response headers: " + result.getHeaders());
System.out.println("Contents: " + result.getBody());

RestClient 也可以使用底層的 Jackson 將 JSON 轉換為物件。實際上,它可以轉換 RestTemplate 支援的所有類型,因為它使用相同的訊息轉換器。請注意 URI 變數的使用,以及 Accept 標頭已設定為 JSON。

int id = ...
Pet pet = restClient.get()
  .uri("https://petclinic.example.com/pets/{id}", id)
  .accept(APPLICATION_JSON)
  .retrieve()
  .body(Pet.class);

POST

執行 POST 請求同樣簡單,如下所示

Pet pet = ...
ResponseEntity<Void> response = restClient.post()
  .uri("https://petclinic.example.com/pets/new")
  .contentType(APPLICATION_JSON)
  .body(pet)
  .retrieve()
  .toBodilessEntity();

錯誤處理

預設情況下,當收到 4xx 或 5xx 狀態碼時,RestClient 會拋出 RestClientException 的子類別。可以使用狀態處理常式覆寫此行為,如下所示

String result = restClient.get()
  .uri("https://example.com/this-url-does-not-exist")
  .retrieve()
  .onStatus(HttpStatusCode::is4xxClientError, (request, response) -> {
      throw new MyCustomRuntimeException(response.getStatusCode(), response.getHeaders())
  })
  .body(String.class);

Exchange

RestClient 為更進階的場景提供了 exchange 方法,因為它可以存取底層的 HTTP 請求和回應。當您使用 exchange 時,先前提及的狀態處理常式會套用,因為 exchange 函數已經提供了對完整回應的存取權,讓您可以執行任何必要的錯誤處理

Pet result = restClient.get()
  .uri("https://petclinic.example.com/pets/{id}", id)
  .accept(APPLICATION_JSON)
  .exchange((request, response) -> {
    if (response.getStatusCode().is4xxClientError()) {
      throw new MyCustomRuntimeException(response.getStatusCode(), response.getHeaders());
    }
    else {
      Pet pet = convertResponse(response);
      return pet;
    }
  });

RestClient 的支援

RestClient 只是 Spring Framework 6.1 提供的眾多功能之一。各種組件已經支援 RestClient:您可以透過 MockRestServiceServer 測試其使用情況,或將其用作 @HttpExchange 介面的後端。

此外,Spring Boot 3.2 M1 將包含對 RestClient 的支援。

訂閱 Spring 電子報

隨時關注 Spring 電子報

訂閱

領先一步

VMware 提供培訓和認證,以加速您的進展。

了解更多

取得支援

Tanzu Spring 在一個簡單的訂閱中提供 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位檔案。

了解更多

即將到來的活動

查看 Spring 社群中所有即將到來的活動。

查看全部