Spring最新HTTP接口调用工具RestClient

2024年 3月 8日 63.4k 0

环境:SpringBoot3.2.1

1. 简介

客户端执行HTTP请求,在底层的HTTP客户端库(如JDK HttpClient、ApacheHttpComponents等)上公开流畅、同步的API。

RestClient是一个同步HTTP客户端,它提供了一个现代、流畅的API。它提供了对HTTP库的抽象,允许从Java对象到HTTP请求的方便转换,以及从HTTP响应创建对象。

2. 创建RestClient实例

RestClient是使用一个静态create方法创建的。还可以通过builder来获得带有进一步选项的builder,例如指定使用哪个HTTP库和使用哪个消息转换器,设置默认URI、默认路径变量、默认请求头或uriBuilderFactory,或注册拦截器和初始化器。

一旦创建(或构建),RestClient就可以被多个线程安全地使用。

示例:

// 简单create方式
RestClient defaultClient = RestClient.create() ;
// 通过builder构建
RestClient customClient = RestClient.builder()
  .requestFactory(new HttpComponentsClientHttpRequestFactory())
  .messageConverters(converters -> converters.add(new PackCustomMessageConverter()))
  .baseUrl("http://api.pack.com")
  .defaultUriVariables(Map.of("name", "zs"))
  .defaultHeader("My-Header", "Foo")
  .requestInterceptor(...)
  .requestInitializer(...)
  .build() ;

3. 使用RestClient

当使用RestClient发出HTTP请求时,首先要指定使用哪个HTTP方法。这可以使用method(HttpMethod),或者使用便利方法get()、head()、post()等来完成。

RestClient restClient = RestClient.create("http://api.pack.com") ;
restClient.get() ;
restClient.post() ;
// 或
restClient.method(HttpMethod.GET) ;

3.1 Request URI

接下来,可以用URI方法指定请求URI。此步骤是可选的,如果RestClient配置了默认URI,则可以跳过此步骤。URL通常指定为字符串,带有可选的URI模板变量。默认情况下,字符串url是编码的,但是可以通过使用自定义uriBuilderFactory构建客户端来更改。

RestClient restClient = RestClient.create("http://api.pack.com") ;
restClient.method(HttpMethod.GET).uri("/users") ;

3.2 Request Headers And Body

如果有必要,可以通过添加请求头header(String, String)、header(Consumer),或者使用便利方法accept(MediaType…)、acceptCharset(Charset…)等来操作HTTP请求。对于可以包含正文(POST、PUT和PATCH)的HTTP请求,还有其他方法:contentType(MediaType)和contentLength(long)。

请求体本身可以通过body(Object)设置,它在内部使用HTTP消息转换。或者,可以使用ParameterizedTypeReference设置请求体,这样就可以使用泛型。最后,函数体可以设置为一个回调函数,用于写入OutputStream。

RestClient restClient = RestClient.create("http://api.pack.com") ;
restClient
  .post()
  .uri("/users")
  .body(new User(666L, "张三", 23))
  .header("X-API-VERSION", "1.0")

3.3 获取响应结果

设置好请求后,调用retrieve()方法访问HTTP响应。可以使用body(Class)或body(ParameterizedTypeReference)来访问响应主体,参数化类型如列表。body方法将响应内容转换为各种类型,例如bytes可以转换为字符串,JSON可以使用Jackson转换为对象等。

响应也可以被转换为ResponseEntity,以便访问响应头和响应体。

RestClient restClient = RestClient.create("http://api.pack.com") ;
restClient
  .get()
  .uri("/users/666")
  .retrieve()
  .body(User.class) ;

通过ResponseEntity可以访问响应的状态码和响应头:

RestClient restClient = RestClient.create("http://api.pack.com") ;
ResponseEntity result = restClient.get() 
  .uri("/users/666") 
  .accept(APPLICATION_JSON)
  .retrieve()
  .toEntity(User.class) ; 
System.out.println("Response status: " + result.getStatusCode()); 
System.out.println("Response headers: " + result.getHeaders()); 
System.out.println("Contents: " + result.getBody());

3.4 错误处理

默认情况下,当返回的状态码为4xx或5xx的响应时,RestClient会抛出RestClientException的子类。这种行为可以用onStatus来覆盖。

String result = restClient.get() 
  .uri("/users/{id}", id) 
  .retrieve()
  // 自定义4xx错误
  .onStatus(HttpStatusCode::is4xxClientError, (request, response) -> { 
    throw new MyCustomRuntimeException(response.getStatusCode(), response.getHeaders()) 
  })
  .body(String.class) ;

onStatus方法

图片图片

3.5 Exchange

对于更高级的场景,RestClient通过exchange方法提供对底层HTTP请求和响应的访问,可以使用该方法代替retrieve()。使用exchange时不会应用状态处理程序,因为exchange方法已经提供了对完整响应的访问,允许执行任何必要的错误处理。

RestClient restClient = RestClient.create("http://api.pack.com") ;
restClient
  .post()
  .uri("/users/666")
  .body(new User())
  .header("X-API-VERSION", "1.0")
  .exchange((request, response) -> {
    if (response.getStatusCode().is4xxClientError()) {
      throw new RuntimeException(String.format("status: %d, headers: %s", response.getStatusCode(), response.getHeaders())) ; 
    } else {
      return response.getBody() ;
    }
  }) ;

3.6 客户端请求工厂

RestClient使用客户端HTTP库来执行HTTP请求。这些库通过ClientRequestFactory接口进行调整。有各种可用的实现:

  • JdkClientHttpRequestFactory for Java’s HttpClient,
  • HttpComponentsClientHttpRequestFactory for use with Apache HTTP Components HttpClient,
  • JettyClientHttpRequestFactory for Jetty’s HttpClient,
  • ReactorNettyClientRequestFactory for Reactor Netty’s HttpClient,
  • SimpleClientHttpRequestFactory as a simple default.

如果在构建RestClient时没有指定请求工厂,它将使用classpath中提供的Apache或Jetty HttpClient。否则,如果加载了java.net.http模块,它将使用Java的HttpClient。

以上是本篇文章的全部内容,希望对你有帮助。

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论