Spring RestClient 使用教程

RestClient 概述

RestClient 是官方在 Spring6.1 版本推出用于替代 RestTemplate 而设计的全新用于与 RESTful Web 服务进行交互的客户端组件。它封装了底层的 HTTP 请求细节,让开发者可以用简洁的代码发送 GET、POST、PUT、DELETE 等请求,并方便地处理 JSON/XML 等格式的响应。它的核心作用就是让你在 Java 代码里像浏览器一样主动发 HTTP 请求,用来调用第三方接口或微服务接口。

官网地址:https://docs.spring.io/spring-framework/reference/6.1/integration/rest-clients.html#rest-restclient

RestClient 使用

1、创建 RestClient

创建 RestClient 有两种方式:
方式一:使用静态的 create 方法

estClient defaultClient = RestClient.create();

方式二:使用 builder() 要获得具有更多选项的构建器,如指定使用哪个HTTP库(请参见客户端请求工厂)以及使用哪些消息转换器(请参见HTTP消息转换),设置默认URI、默认路径变量、默认请求头或uriBuilderFactory或者注册拦截器和初始化器。

RestClient customClient = RestClient.builder()
  .requestFactory(new HttpComponentsClientHttpRequestFactory())
  .messageConverters(converters -> converters.add(new MyCustomMessageConverter()))
  .baseUrl("https://example.com")
  .defaultUriVariables(Map.of("variable", "foo"))
  .defaultHeader("My-Header", "Foo")
  .requestInterceptor(myCustomInterceptor)
  .requestInitializer(myCustomInitializer)
  .build();
2、使用 RestClient
1)请求URL

首先要指定的是使用哪种HTTP方法。这可以通过method(HttpMethod)或者用方便的方法get(), head(), post(),等等。默认情况下,字符串URL是编码的.

int id = 42;
restClient.get()
  .uri("https://example.com/orders/{id}", id)
....
2)headers(请求头)

如果有必要,可以通过添加带有header(String, String), headers(Consumer,或者用方便的方法accept(MediaType…​), acceptCharset(Charset…​)诸如此类。对于可以包含正文的HTTP请求(POST, PUT,以及PATCH),还可以使用其他方法:contentType(MediaType),以及contentLength(long)。

3)body(请求体)

请求主体本身可以通过以下方式设置 body(Object),它在内部使用HTTP消息转换。或者,可以使用ParameterizedTypeReference,允许您使用泛型。最后,可以将主体设置为一个回调函数,该函数写入OutputStream。

4)response(响应)

1、响应转为字符串

String result = restClient.get()
  .uri("https://example.com")
  .retrieve()
  .body(String.class); // 响应转为字符串

System.out.println(result);

2、响应转为ResponseEntity

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

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

3、将响应json转为实体类

int id = ...;
Pet pet = restClient.get()
  .uri("https://petclinic.example.com/pets/{id}", id)
  .accept(APPLICATION_JSON)
  .retrieve()
  .body(Pet.class); // 将响应json转为实体类

4、post请求将实体类转为json

Pet pet = ...
ResponseEntity<Void> response = restClient.post()
  .uri("https://petclinic.example.com/pets/new")
  .contentType(APPLICATION_JSON)
  .body(pet) // post请求将实体类转为json
  .retrieve()
  .toBodilessEntity();
5)错误处理

默认情况下,RestClient引发的子类RestClientException检索带有4xx或5xx状态代码的响应时。此行为可以使用onStatus

String result = restClient.get()
  .uri("https://example.com/this-url-does-not-exist")
  .retrieve()
  .onStatus(HttpStatusCode::is4xxClientError, (request, response) -> { // 4xx响应码抛自定义异常
      throw new MyCustomRuntimeException(response.getStatusCode(), response.getHeaders());
  })
  .body(String.class);
6)Exchange

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

Pet result = restClient.get()
  .uri("https://petclinic.example.com/pets/{id}", id)
  .accept(APPLICATION_JSON)
  .exchange((request, response) -> { // exchange提供请求和响应
    if (response.getStatusCode().is4xxClientError()) {
      throw new MyCustomRuntimeException(response.getStatusCode(), response.getHeaders());
    }
    else {
      Pet pet = convertResponse(response); // 将响应转换成Pet域对象
      return pet;
    }
  });
7)Multipart数据

要发送Multipart数据,需要提供一个MultiValueMap<String, Object>其值可能是Object对于零件内容,一个Resource对于文件部分,或HttpEntity对于带标题的零件内容。例如:

MultiValueMap<String, Object> parts = new LinkedMultiValueMap<>();

parts.add("fieldPart", "fieldValue");
parts.add("filePart", new FileSystemResource("...logo.png"));
parts.add("jsonPart", new Person("Jason"));

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_XML);
parts.add("xmlPart", new HttpEntity<>(myBean, headers));

// send using RestClient.post or RestTemplate.postForEntity

在大多数情况下,您不必指定Content-Type对于每一部分。内容类型是根据HttpMessageConverter选择序列化它,或者,在Resource,基于文件扩展名。如有必要,您可以显式提供MediaType用一个HttpEntity包装纸。

一旦MultiValueMap已经准备好了,您可以将它用作POST请求,使用RestClient.post().body(parts)(或者RestTemplate.postForObject).

如果MultiValueMap包含至少一个非String价值Content-Type设置为multipart/form -data由FormHttpMessageConverter。如果MultiValueMap有String价值观Content-Type默认为application/x-www-form-urlencoded。如有必要Content-Type也可以显式设置。

一句话总结

Spring RestClient 是 Spring Framework 6.1+ 引入的同步、流式 REST 客户端,定位是“用 WebClient 风格的 API 做 RestTemplate 的事”,底层可走 JDK HttpClient、Apache HttpComponents 等,复用 Spring 的消息转换器、拦截器、请求工厂等基础设施。

注:适用版本:Spring 6.1+,Spring Boot 3.2+

posted @ 2026-09-14 23:27  Binge-和时间做朋友  阅读(23)  评论(0)    收藏  举报