Spring 6.1 新特性:RestClient

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

Spring Framework 6.1 M2 引入了 RestClient,一个新的同步 HTTP 客户端。顾名思义,RestClient 提供了 WebClient 的流畅 API 以及 RestTemplate 的基础设施。

十四年前,当 RestTemplate 在 Spring Framework 3.0 中被引入时,我们很快发现,在一个模板类中暴露 HTTP 的所有能力会导致过多的重载方法。因此,在 Spring Framework 5 中,我们为响应式 WebClient 使用了流畅 API。借助 RestClient,我们引入了一个提供类似于 WebClient API 的 HTTP 客户端,并且它使用 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 也可以将 JSON 转换为对象,底层使用了 Jackson。实际上,它可以使用与 RestTemplate 相同的消息转换器,因此可以转换 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 社区中即将举行的所有活动。

查看全部