如果在构建RestClient时没有指定请求工厂,它将使用classpath中提供的Apache或Jetty HttpClient。否则,如果加载了java.net.http模块,它将使用Java的HttpClient。
环境: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.2RequestHeaders And Body
如果有必要,可以通过添加请求头header(String, String)、header(Consumer<HttpHeaders>),或者使用便利方法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<String> 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.5Exchange
对于更高级的场景,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接口进行调整。有各种可用的实现:
- JdkClientHttpRequestFactoryfor Java’sHttpClient,
- HttpComponentsClientHttpRequestFactoryfor use with Apache HTTP ComponentsHttpClient,
- JettyClientHttpRequestFactoryfor Jetty’sHttpClient,
- ReactorNettyClientRequestFactoryfor Reactor Netty’sHttpClient,
- SimpleClientHttpRequestFactoryas a simple default.
如果在构建RestClient时没有指定请求工厂,它将使用classpath中提供的Apache或Jetty HttpClient。否则,如果加载了java.net.http模块,它将使用Java的HttpClient。
以上是本篇文章的全部内容,希望对你有帮助。
©本文为清一色官方代发,观点仅代表作者本人,与清一色无关。清一色对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文不作为投资理财建议,请读者仅作参考,并请自行承担全部责任。文中部分文字/图片/视频/音频等来源于网络,如侵犯到著作权人的权利,请与我们联系(微信/QQ:1074760229)。转载请注明出处:清一色财经