此版本仍在开发中,尚未被视为稳定版本。最新的稳定版本请使用 Spring Framework 6.1.13spring-doc.cn

此版本仍在开发中,尚未被视为稳定版本。最新的稳定版本请使用 Spring Framework 6.1.13spring-doc.cn

Spring 框架提供了以下选项来调用 REST 端点:spring-doc.cn

RestClient

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

创建RestClient

是使用其中一种 static 方法创建的。 您还可以用于获取具有更多选项的构建器,例如指定要使用的 HTTP 库(请参阅客户端请求工厂)和要使用的消息转换器(请参阅HTTP 消息转换)、设置默认 URI、默认路径变量、默认请求标头或 ,或者注册拦截器和初始值设定项。RestClientcreatebuilder()uriBuilderFactoryspring-doc.cn

一旦创建(或构建),就可以被多个线程安全地使用。RestClientspring-doc.cn

以下示例显示如何创建默认 ,以及如何构建自定义默认。RestClientspring-doc.cn

RestClient defaultClient = RestClient.create();

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();
val defaultClient = RestClient.create()

val customClient = RestClient.builder()
  .requestFactory(HttpComponentsClientHttpRequestFactory())
  .messageConverters { converters -> converters.add(MyCustomMessageConverter()) }
  .baseUrl("https://example.com")
  .defaultUriVariables(mapOf("variable" to "foo"))
  .defaultHeader("My-Header", "Foo")
  .requestInterceptor(myCustomInterceptor)
  .requestInitializer(myCustomInitializer)
  .build()

使用RestClient

使用 发出 HTTP 请求时,首先要指定的是要使用的 HTTP 方法。 这可以通过 或 便捷方法 、 、 等来完成。RestClientmethod(HttpMethod)get()head()post()spring-doc.cn

请求 URL

接下来,可以使用方法指定请求 URI。 此步骤是可选的,如果配置了默认 URI,则可以跳过此步骤。 URL 通常指定为 ,其中包含可选的 URI 模板变量。 以下示例将 GET 请求配置为:uriRestClientStringexample.com/orders/42spring-doc.cn

int id = 42;
restClient.get()
  .uri("https://example.com/orders/{id}", id)
  ....
val id = 42
restClient.get()
  .uri("https://example.com/orders/{id}", id)
  ...

函数还可用于更多控制,例如指定请求参数spring-doc.cn

默认情况下,字符串 URL 是编码的,但这可以通过使用自定义 . URL 也可以随 function 或 as a 一起提供,这两者都未编码。 有关使用 URI 和编码 URI 的更多详细信息,请参阅 URI 链接uriBuilderFactoryjava.net.URIspring-doc.cn

请求标头和正文

如有必要,可以通过使用 、 或 convenience methods 等添加请求标头来操作 HTTP 请求。 对于可以包含正文(、 和 )的 HTTP 请求,可以使用其他方法:和 。header(String, String)headers(Consumer<HttpHeaders>accept(MediaType…​)acceptCharset(Charset…​)POSTPUTPATCHcontentType(MediaType)contentLength(long)spring-doc.cn

请求正文本身可以通过 设置,它在内部使用 HTTP 消息转换。 或者,可以使用 设置请求正文 ,从而允许您使用泛型。 最后,可以将 body 设置为写入 .body(Object)ParameterizedTypeReferenceOutputStreamspring-doc.cn

检索响应

设置请求后,通过调用 来访问 HTTP 响应 。 可以使用 或 对于参数化类型(如 lists)来访问响应正文。 该方法将响应内容转换为各种类型,例如,字节可以转换为 ,JSON 可以使用 Jackson 转换为对象,等等(请参阅 HTTP 消息转换)。retrieve()body(Class)body(ParameterizedTypeReference)bodyStringspring-doc.cn

响应还可以转换为 ,从而访问响应标头和正文。ResponseEntityspring-doc.cn

此示例演示如何用于执行简单请求。RestClientGETspring-doc.cn

String result = restClient.get() (1)
  .uri("https://example.com") (2)
  .retrieve() (3)
  .body(String.class); (4)

System.out.println(result); (5)
1 设置 GET 请求
2 指定要连接到的 URL
3 检索响应
4 将响应转换为字符串
5 打印结果
val result= restClient.get() (1)
  .uri("https://example.com") (2)
  .retrieve() (3)
  .body<String>() (4)

println(result) (5)
1 设置 GET 请求
2 指定要连接到的 URL
3 检索响应
4 将响应转换为字符串
5 打印结果

通过以下方式提供对响应状态代码和标头的访问:ResponseEntityspring-doc.cn

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

System.out.println("Response status: " + result.getStatusCode()); (3)
System.out.println("Response headers: " + result.getHeaders()); (3)
System.out.println("Contents: " + result.getBody()); (3)
1 为指定 URL 设置 GET 请求
2 将响应转换为ResponseEntity
3 打印结果
val result = restClient.get() (1)
  .uri("https://example.com") (1)
  .retrieve()
  .toEntity<String>() (2)

println("Response status: " + result.statusCode) (3)
println("Response headers: " + result.headers) (3)
println("Contents: " + result.body) (3)
1 为指定 URL 设置 GET 请求
2 将响应转换为ResponseEntity
3 打印结果

RestClient可以使用 Jackson 库将 JSON 转换为对象。 请注意此示例中 URI 变量的用法,并且标头设置为 JSON。Acceptspring-doc.cn

int id = ...;
Pet pet = restClient.get()
  .uri("https://petclinic.example.com/pets/{id}", id) (1)
  .accept(APPLICATION_JSON) (2)
  .retrieve()
  .body(Pet.class); (3)
1 使用 URI 变量
2 将标头设置为Acceptapplication/json
3 将 JSON 响应转换为域对象Pet
val id = ...
val pet = restClient.get()
  .uri("https://petclinic.example.com/pets/{id}", id) (1)
  .accept(APPLICATION_JSON) (2)
  .retrieve()
  .body<Pet>() (3)
1 使用 URI 变量
2 将标头设置为Acceptapplication/json
3 将 JSON 响应转换为域对象Pet

在下一个示例中,用于执行包含 JSON 的 POST 请求,该请求再次使用 Jackson 进行转换。RestClientspring-doc.cn

Pet pet = ... (1)
ResponseEntity<Void> response = restClient.post() (2)
  .uri("https://petclinic.example.com/pets/new") (2)
  .contentType(APPLICATION_JSON) (3)
  .body(pet) (4)
  .retrieve()
  .toBodilessEntity(); (5)
1 创建域对象Pet
2 设置 POST 请求和要连接到的 URL
3 将标头设置为Content-Typeapplication/json
4 用作请求正文pet
5 将响应转换为没有正文的响应实体。
val pet: Pet = ... (1)
val response = restClient.post() (2)
  .uri("https://petclinic.example.com/pets/new") (2)
  .contentType(APPLICATION_JSON) (3)
  .body(pet) (4)
  .retrieve()
  .toBodilessEntity() (5)
1 创建域对象Pet
2 设置 POST 请求和要连接到的 URL
3 将标头设置为Content-Typeapplication/json
4 用作请求正文pet
5 将响应转换为没有正文的响应实体。

错误处理

默认情况下,在检索具有 4xx 或 5xx 状态代码的响应时,会引发子类 of。 可以使用 覆盖此行为。RestClientRestClientExceptiononStatusspring-doc.cn

String result = restClient.get() (1)
  .uri("https://example.com/this-url-does-not-exist") (1)
  .retrieve()
  .onStatus(HttpStatusCode::is4xxClientError, (request, response) -> { (2)
      throw new MyCustomRuntimeException(response.getStatusCode(), response.getHeaders()); (3)
  })
  .body(String.class);
1 为返回 404 状态代码的 URL 创建 GET 请求
2 为所有 4xx 状态代码设置状态处理程序
3 引发自定义异常
val result = restClient.get() (1)
  .uri("https://example.com/this-url-does-not-exist") (1)
  .retrieve()
  .onStatus(HttpStatusCode::is4xxClientError) { _, response -> (2)
    throw MyCustomRuntimeException(response.getStatusCode(), response.getHeaders()) } (3)
  .body<String>()
1 为返回 404 状态代码的 URL 创建 GET 请求
2 为所有 4xx 状态代码设置状态处理程序
3 引发自定义异常

交换

对于更高级的方案,可以通过该方法访问基础 HTTP 请求和响应,该方法可用于代替 . 使用 时不应用 Status 处理程序,因为 exchange 函数已经提供了对完整响应的访问,从而允许您执行任何必要的错误处理。RestClientexchange()retrieve()exchange()spring-doc.cn

Pet result = restClient.get()
  .uri("https://petclinic.example.com/pets/{id}", id)
  .accept(APPLICATION_JSON)
  .exchange((request, response) -> { (1)
    if (response.getStatusCode().is4xxClientError()) { (2)
      throw new MyCustomRuntimeException(response.getStatusCode(), response.getHeaders()); (2)
    }
    else {
      Pet pet = convertResponse(response); (3)
      return pet;
    }
  });
1 exchange提供请求和响应
2 当响应具有 4xx 状态代码时引发异常
3 将响应转换为 Pet 域对象
val result = restClient.get()
  .uri("https://petclinic.example.com/pets/{id}", id)
  .accept(MediaType.APPLICATION_JSON)
  .exchange { request, response -> (1)
    if (response.getStatusCode().is4xxClientError()) { (2)
      throw MyCustomRuntimeException(response.getStatusCode(), response.getHeaders()) (2)
    } else {
      val pet: Pet = convertResponse(response) (3)
      pet
    }
  }
1 exchange提供请求和响应
2 当响应具有 4xx 状态代码时引发异常
3 将响应转换为 Pet 域对象

HTTP 消息转换

Jackson JSON 视图

要仅序列化对象属性的子集,您可以指定 Jackson JSON 视图,如下例所示:spring-doc.cn

MappingJacksonValue value = new MappingJacksonValue(new User("eric", "7!jd#h23"));
value.setSerializationView(User.WithoutPasswordView.class);

ResponseEntity<Void> response = restClient.post() // or RestTemplate.postForEntity
  .contentType(APPLICATION_JSON)
  .body(value)
  .retrieve()
  .toBodilessEntity();

多部分

要发送多部分数据,您需要提供 a,其值可以是 for part 内容、for file part 或带有标题的 for part 内容。 例如:MultiValueMap<String, Object>ObjectResourceHttpEntityspring-doc.cn

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-TypeHttpMessageConverterResourceMediaTypeHttpEntityspring-doc.cn

准备就绪后,您可以使用 (或 ) 将其用作请求的正文。MultiValueMapPOSTRestClient.post().body(parts)RestTemplate.postForObjectspring-doc.cn

如果 至少包含一个非值,则 由 设置为 。 如果 has 值,则默认为 . 如有必要,也可以显式设置 。MultiValueMapStringContent-Typemultipart/form-dataFormHttpMessageConverterMultiValueMapStringContent-Typeapplication/x-www-form-urlencodedContent-Typespring-doc.cn

客户端请求工厂

要执行 HTTP 请求,请使用客户端 HTTP 库。 这些库通过界面进行调整。 有多种实现可供选择:RestClientClientRequestFactoryspring-doc.cn

  • JdkClientHttpRequestFactory对于 Java 的HttpClientspring-doc.cn

  • HttpComponentsClientHttpRequestFactory用于 Apache HTTP 组件HttpClientspring-doc.cn

  • JettyClientHttpRequestFactoryJetty's (Jetty)HttpClientspring-doc.cn

  • ReactorNettyClientRequestFactory用于 Reactor Netty'sHttpClientspring-doc.cn

  • SimpleClientHttpRequestFactory作为简单的默认值spring-doc.cn

如果在构建时没有指定请求工厂,它将使用 Apache 或 Jetty(如果它们在 Classpath 上可用)。 否则,如果加载了模块,它将使用 Java 的 . 最后,它将采用简单的默认值。RestClientHttpClientjava.net.httpHttpClientspring-doc.cn

请注意,在访问表示错误的响应的状态(例如 401)时,可能会引发异常。 如果这是一个问题,请使用任何替代请求工厂。SimpleClientHttpRequestFactory
1 设置 GET 请求
2 指定要连接到的 URL
3 检索响应
4 将响应转换为字符串
5 打印结果
1 设置 GET 请求
2 指定要连接到的 URL
3 检索响应
4 将响应转换为字符串
5 打印结果
1 为指定 URL 设置 GET 请求
2 将响应转换为ResponseEntity
3 打印结果
1 为指定 URL 设置 GET 请求
2 将响应转换为ResponseEntity
3 打印结果
1 使用 URI 变量
2 将标头设置为Acceptapplication/json
3 将 JSON 响应转换为域对象Pet
1 使用 URI 变量
2 将标头设置为Acceptapplication/json
3 将 JSON 响应转换为域对象Pet
1 创建域对象Pet
2 设置 POST 请求和要连接到的 URL
3 将标头设置为Content-Typeapplication/json
4 用作请求正文pet
5 将响应转换为没有正文的响应实体。
1 创建域对象Pet
2 设置 POST 请求和要连接到的 URL
3 将标头设置为Content-Typeapplication/json
4 用作请求正文pet
5 将响应转换为没有正文的响应实体。
1 为返回 404 状态代码的 URL 创建 GET 请求
2 为所有 4xx 状态代码设置状态处理程序
3 引发自定义异常
1 为返回 404 状态代码的 URL 创建 GET 请求
2 为所有 4xx 状态代码设置状态处理程序
3 引发自定义异常
1 exchange提供请求和响应
2 当响应具有 4xx 状态代码时引发异常
3 将响应转换为 Pet 域对象
1 exchange提供请求和响应
2 当响应具有 4xx 状态代码时引发异常
3 将响应转换为 Pet 域对象
请注意,在访问表示错误的响应的状态(例如 401)时,可能会引发异常。 如果这是一个问题,请使用任何替代请求工厂。SimpleClientHttpRequestFactory

WebClient

WebClient是执行 HTTP 请求的非阻塞反应式客户端。它是 在 5.0 中引入,并提供了 的替代方案,支持 同步、异步和流式处理方案。RestTemplatespring-doc.cn

WebClient支持以下内容:spring-doc.cn

有关更多详细信息,请参阅 WebClientspring-doc.cn

RestTemplate

它以经典的 Spring Template 类的形式通过 HTTP 客户端库提供高级 API。 它公开了以下重载方法组:RestTemplatespring-doc.cn

RestClient 为同步 HTTP 访问提供了更现代的 API。 对于异步和流式处理方案,请考虑反应式 WebClient
表 1.RestTemplate 方法
“方法”组 描述

getForObjectspring-doc.cn

通过 GET 检索表示形式。spring-doc.cn

getForEntityspring-doc.cn

使用 GET 检索 (即 status、headers 和 body)。ResponseEntityspring-doc.cn

headForHeadersspring-doc.cn

使用 HEAD 检索资源的所有标头。spring-doc.cn

postForLocationspring-doc.cn

使用 POST 创建新资源,并从响应中返回标头。Locationspring-doc.cn

postForObjectspring-doc.cn

使用 POST 创建新资源,并从响应中返回表示形式。spring-doc.cn

postForEntityspring-doc.cn

使用 POST 创建新资源,并从响应中返回表示形式。spring-doc.cn

putspring-doc.cn

使用 PUT 创建或更新资源。spring-doc.cn

patchForObjectspring-doc.cn

使用 PATCH 更新资源并从响应中返回表示形式。 请注意,JDK 不支持 ,但 Apache HttpComponents 和其他支持。HttpURLConnectionPATCHspring-doc.cn

deletespring-doc.cn

使用 DELETE 删除指定 URI 处的资源。spring-doc.cn

optionsForAllowspring-doc.cn

使用 ALLOW 检索资源允许的 HTTP 方法。spring-doc.cn

exchangespring-doc.cn

上述方法的更通用(且不那么固执己见)版本,可在需要时提供额外的灵活性。 它接受一个(包括 HTTP 方法、URL、标头和正文作为输入)并返回一个 .RequestEntityResponseEntityspring-doc.cn

这些方法允许使用 of 而不是来指定 具有泛型的响应类型。ParameterizedTypeReferenceClassspring-doc.cn

executespring-doc.cn

执行请求的最通用方式,可完全控制请求 通过回调接口进行准备和响应提取。spring-doc.cn

初始化

RestTemplate使用与 . 默认情况下,它使用 ,但这可以通过构造函数进行更改。 参见 客户端请求工厂RestClientSimpleClientHttpRequestFactoryspring-doc.cn

RestTemplate可以进行检测以实现可观测性,以便生成指标和跟踪。 请参阅 RestTemplate 可观察性支持部分。

身体

传入和返回方法的对象在 HTTP 消息的帮助下与 HTTP 消息相互转换,请参阅 HTTP 消息转换RestTemplateHttpMessageConverterspring-doc.cn

从 迁移到RestTemplateRestClient

下表显示了方法的等效项。 它可用于从后者迁移到前者。RestClientRestTemplatespring-doc.cn

表 2.RestTemplate 方法的 RestClient 等效项
RestTemplate方法 RestClient等效

getForObject(String, Class, Object…​)spring-doc.cn

get() .uri(String, Object…​) .retrieve() .body(Class)spring-doc.cn

getForObject(String, Class, Map)spring-doc.cn

get() .uri(String, Map) .retrieve() .body(Class)spring-doc.cn

getForObject(URI, Class)spring-doc.cn

get() .uri(URI) .retrieve() .body(Class)spring-doc.cn

getForEntity(String, Class, Object…​)spring-doc.cn

get() .uri(String, Object…​) .retrieve() .toEntity(Class)spring-doc.cn

getForEntity(String, Class, Map)spring-doc.cn

get() .uri(String, Map) .retrieve() .toEntity(Class)spring-doc.cn

getForEntity(URI, Class)spring-doc.cn

get() .uri(URI) .retrieve() .toEntity(Class)spring-doc.cn

headForHeaders(String, Object…​)spring-doc.cn

head() .uri(String, Object…​) .retrieve() .toBodilessEntity() .getHeaders()spring-doc.cn

headForHeaders(String, Map)spring-doc.cn

head() .uri(String, Map) .retrieve() .toBodilessEntity() .getHeaders()spring-doc.cn

headForHeaders(URI)spring-doc.cn

head() .uri(URI) .retrieve() .toBodilessEntity() .getHeaders()spring-doc.cn

postForLocation(String, Object, Object…​)spring-doc.cn

post() .uri(String, Object…​) .body(Object).retrieve() .toBodilessEntity() .getLocation()spring-doc.cn

postForLocation(String, Object, Map)spring-doc.cn

post() .uri(String, Map) .body(Object) .retrieve() .toBodilessEntity() .getLocation()spring-doc.cn

postForLocation(URI, Object)spring-doc.cn

post() .uri(URI) .body(Object) .retrieve() .toBodilessEntity() .getLocation()spring-doc.cn

postForObject(String, Object, Class, Object…​)spring-doc.cn

post() .uri(String, Object…​) .body(Object) .retrieve() .body(Class)spring-doc.cn

postForObject(String, Object, Class, Map)spring-doc.cn

post() .uri(String, Map) .body(Object) .retrieve() .body(Class)spring-doc.cn

postForObject(URI, Object, Class)spring-doc.cn

post() .uri(URI) .body(Object) .retrieve() .body(Class)spring-doc.cn

postForEntity(String, Object, Class, Object…​)spring-doc.cn

post() .uri(String, Object…​) .body(Object) .retrieve() .toEntity(Class)spring-doc.cn

postForEntity(String, Object, Class, Map)spring-doc.cn

post() .uri(String, Map) .body(Object) .retrieve() .toEntity(Class)spring-doc.cn

postForEntity(URI, Object, Class)spring-doc.cn

post() .uri(URI) .body(Object) .retrieve() .toEntity(Class)spring-doc.cn

put(String, Object, Object…​)spring-doc.cn

put() .uri(String, Object…​) .body(Object) .retrieve() .toBodilessEntity()spring-doc.cn

put(String, Object, Map)spring-doc.cn

put() .uri(String, Map) .body(Object) .retrieve() .toBodilessEntity()spring-doc.cn

put(URI, Object)spring-doc.cn

put() .uri(URI) .body(Object) .retrieve() .toBodilessEntity()spring-doc.cn

patchForObject(String, Object, Class, Object…​)spring-doc.cn

patch() .uri(String, Object…​) .body(Object) .retrieve() .body(Class)spring-doc.cn

patchForObject(String, Object, Class, Map)spring-doc.cn

patch() .uri(String, Map) .body(Object) .retrieve() .body(Class)spring-doc.cn

patchForObject(URI, Object, Class)spring-doc.cn

patch() .uri(URI) .body(Object) .retrieve() .body(Class)spring-doc.cn

delete(String, Object…​)spring-doc.cn

delete() .uri(String, Object…​) .retrieve() .toBodilessEntity()spring-doc.cn

delete(String, Map)spring-doc.cn

delete() .uri(String, Map) .retrieve() .toBodilessEntity()spring-doc.cn

delete(URI)spring-doc.cn

delete() .uri(URI) .retrieve() .toBodilessEntity()spring-doc.cn

optionsForAllow(String, Object…​)spring-doc.cn

options() .uri(String, Object…​) .retrieve() .toBodilessEntity() .getAllow()spring-doc.cn

optionsForAllow(String, Map)spring-doc.cn

options() .uri(String, Map) .retrieve() .toBodilessEntity() .getAllow()spring-doc.cn

optionsForAllow(URI)spring-doc.cn

options() .uri(URI) .retrieve() .toBodilessEntity() .getAllow()spring-doc.cn

exchange(String, HttpMethod, HttpEntity, Class, Object…​)spring-doc.cn

method(HttpMethod) .uri(String, Object…​) .headers(Consumer<HttpHeaders>) .body(Object) .retrieve() .toEntity(Class) [1]spring-doc.cn

exchange(String, HttpMethod, HttpEntity, Class, Map)spring-doc.cn

method(HttpMethod) .uri(String, Map) .headers(Consumer<HttpHeaders>) .body(Object) .retrieve() .toEntity(Class) [1]spring-doc.cn

exchange(URI, HttpMethod, HttpEntity, Class)spring-doc.cn

method(HttpMethod) .uri(URI) .headers(Consumer<HttpHeaders>) .body(Object) .retrieve() .toEntity(Class) [1]spring-doc.cn

exchange(String, HttpMethod, HttpEntity, ParameterizedTypeReference, Object…​)spring-doc.cn

method(HttpMethod) .uri(String, Object…​) .headers(Consumer<HttpHeaders>) .body(Object) .retrieve() .toEntity(ParameterizedTypeReference) [1]spring-doc.cn

exchange(String, HttpMethod, HttpEntity, ParameterizedTypeReference, Map)spring-doc.cn

method(HttpMethod) .uri(String, Map) .headers(Consumer<HttpHeaders>) .body(Object) .retrieve() .toEntity(ParameterizedTypeReference) [1]spring-doc.cn

exchange(URI, HttpMethod, HttpEntity, ParameterizedTypeReference)spring-doc.cn

method(HttpMethod) .uri(URI) .headers(Consumer<HttpHeaders>) .body(Object) .retrieve() .toEntity(ParameterizedTypeReference) [1]spring-doc.cn

exchange(RequestEntity, Class)spring-doc.cn

method(HttpMethod) .uri(URI) .headers(Consumer<HttpHeaders>) .body(Object) .retrieve() .toEntity(Class) [2]spring-doc.cn

exchange(RequestEntity, ParameterizedTypeReference)spring-doc.cn

method(HttpMethod) .uri(URI) .headers(Consumer<HttpHeaders>) .body(Object) .retrieve() .toEntity(ParameterizedTypeReference) [2]spring-doc.cn

execute(String, HttpMethod, RequestCallback, ResponseExtractor, Object…​)spring-doc.cn

method(HttpMethod) .uri(String, Object…​) .exchange(ExchangeFunction)spring-doc.cn

execute(String, HttpMethod, RequestCallback, ResponseExtractor, Map)spring-doc.cn

method(HttpMethod) .uri(String, Map) .exchange(ExchangeFunction)spring-doc.cn

execute(URI, HttpMethod, RequestCallback, ResponseExtractor)spring-doc.cn

method(HttpMethod) .uri(URI) .exchange(ExchangeFunction)spring-doc.cn

RestClient 为同步 HTTP 访问提供了更现代的 API。 对于异步和流式处理方案,请考虑反应式 WebClient
表 1.RestTemplate 方法
“方法”组 描述

getForObjectspring-doc.cn

通过 GET 检索表示形式。spring-doc.cn

getForEntityspring-doc.cn

使用 GET 检索 (即 status、headers 和 body)。ResponseEntityspring-doc.cn

headForHeadersspring-doc.cn

使用 HEAD 检索资源的所有标头。spring-doc.cn

postForLocationspring-doc.cn

使用 POST 创建新资源,并从响应中返回标头。Locationspring-doc.cn

postForObjectspring-doc.cn

使用 POST 创建新资源,并从响应中返回表示形式。spring-doc.cn

postForEntityspring-doc.cn

使用 POST 创建新资源,并从响应中返回表示形式。spring-doc.cn

putspring-doc.cn

使用 PUT 创建或更新资源。spring-doc.cn

patchForObjectspring-doc.cn

使用 PATCH 更新资源并从响应中返回表示形式。 请注意,JDK 不支持 ,但 Apache HttpComponents 和其他支持。HttpURLConnectionPATCHspring-doc.cn

deletespring-doc.cn

使用 DELETE 删除指定 URI 处的资源。spring-doc.cn

optionsForAllowspring-doc.cn

使用 ALLOW 检索资源允许的 HTTP 方法。spring-doc.cn

exchangespring-doc.cn

上述方法的更通用(且不那么固执己见)版本,可在需要时提供额外的灵活性。 它接受一个(包括 HTTP 方法、URL、标头和正文作为输入)并返回一个 .RequestEntityResponseEntityspring-doc.cn

这些方法允许使用 of 而不是来指定 具有泛型的响应类型。ParameterizedTypeReferenceClassspring-doc.cn

executespring-doc.cn

执行请求的最通用方式,可完全控制请求 通过回调接口进行准备和响应提取。spring-doc.cn

RestTemplate可以进行检测以实现可观测性,以便生成指标和跟踪。 请参阅 RestTemplate 可观察性支持部分。
表 2.RestTemplate 方法的 RestClient 等效项
RestTemplate方法 RestClient等效

getForObject(String, Class, Object…​)spring-doc.cn

get() .uri(String, Object…​) .retrieve() .body(Class)spring-doc.cn

getForObject(String, Class, Map)spring-doc.cn

get() .uri(String, Map) .retrieve() .body(Class)spring-doc.cn

getForObject(URI, Class)spring-doc.cn

get() .uri(URI) .retrieve() .body(Class)spring-doc.cn

getForEntity(String, Class, Object…​)spring-doc.cn

get() .uri(String, Object…​) .retrieve() .toEntity(Class)spring-doc.cn

getForEntity(String, Class, Map)spring-doc.cn

get() .uri(String, Map) .retrieve() .toEntity(Class)spring-doc.cn

getForEntity(URI, Class)spring-doc.cn

get() .uri(URI) .retrieve() .toEntity(Class)spring-doc.cn

headForHeaders(String, Object…​)spring-doc.cn

head() .uri(String, Object…​) .retrieve() .toBodilessEntity() .getHeaders()spring-doc.cn

headForHeaders(String, Map)spring-doc.cn

head() .uri(String, Map) .retrieve() .toBodilessEntity() .getHeaders()spring-doc.cn

headForHeaders(URI)spring-doc.cn

head() .uri(URI) .retrieve() .toBodilessEntity() .getHeaders()spring-doc.cn

postForLocation(String, Object, Object…​)spring-doc.cn

post() .uri(String, Object…​) .body(Object).retrieve() .toBodilessEntity() .getLocation()spring-doc.cn

postForLocation(String, Object, Map)spring-doc.cn

post() .uri(String, Map) .body(Object) .retrieve() .toBodilessEntity() .getLocation()spring-doc.cn

postForLocation(URI, Object)spring-doc.cn

post() .uri(URI) .body(Object) .retrieve() .toBodilessEntity() .getLocation()spring-doc.cn

postForObject(String, Object, Class, Object…​)spring-doc.cn

post() .uri(String, Object…​) .body(Object) .retrieve() .body(Class)spring-doc.cn

postForObject(String, Object, Class, Map)spring-doc.cn

post() .uri(String, Map) .body(Object) .retrieve() .body(Class)spring-doc.cn

postForObject(URI, Object, Class)spring-doc.cn

post() .uri(URI) .body(Object) .retrieve() .body(Class)spring-doc.cn

postForEntity(String, Object, Class, Object…​)spring-doc.cn

post() .uri(String, Object…​) .body(Object) .retrieve() .toEntity(Class)spring-doc.cn

postForEntity(String, Object, Class, Map)spring-doc.cn

post() .uri(String, Map) .body(Object) .retrieve() .toEntity(Class)spring-doc.cn

postForEntity(URI, Object, Class)spring-doc.cn

post() .uri(URI) .body(Object) .retrieve() .toEntity(Class)spring-doc.cn

put(String, Object, Object…​)spring-doc.cn

put() .uri(String, Object…​) .body(Object) .retrieve() .toBodilessEntity()spring-doc.cn

put(String, Object, Map)spring-doc.cn

put() .uri(String, Map) .body(Object) .retrieve() .toBodilessEntity()spring-doc.cn

put(URI, Object)spring-doc.cn

put() .uri(URI) .body(Object) .retrieve() .toBodilessEntity()spring-doc.cn

patchForObject(String, Object, Class, Object…​)spring-doc.cn

patch() .uri(String, Object…​) .body(Object) .retrieve() .body(Class)spring-doc.cn

patchForObject(String, Object, Class, Map)spring-doc.cn

patch() .uri(String, Map) .body(Object) .retrieve() .body(Class)spring-doc.cn

patchForObject(URI, Object, Class)spring-doc.cn

patch() .uri(URI) .body(Object) .retrieve() .body(Class)spring-doc.cn

delete(String, Object…​)spring-doc.cn

delete() .uri(String, Object…​) .retrieve() .toBodilessEntity()spring-doc.cn

delete(String, Map)spring-doc.cn

delete() .uri(String, Map) .retrieve() .toBodilessEntity()spring-doc.cn

delete(URI)spring-doc.cn

delete() .uri(URI) .retrieve() .toBodilessEntity()spring-doc.cn

optionsForAllow(String, Object…​)spring-doc.cn

options() .uri(String, Object…​) .retrieve() .toBodilessEntity() .getAllow()spring-doc.cn

optionsForAllow(String, Map)spring-doc.cn

options() .uri(String, Map) .retrieve() .toBodilessEntity() .getAllow()spring-doc.cn

optionsForAllow(URI)spring-doc.cn

options() .uri(URI) .retrieve() .toBodilessEntity() .getAllow()spring-doc.cn

exchange(String, HttpMethod, HttpEntity, Class, Object…​)spring-doc.cn

method(HttpMethod) .uri(String, Object…​) .headers(Consumer<HttpHeaders>) .body(Object) .retrieve() .toEntity(Class) [1]spring-doc.cn

exchange(String, HttpMethod, HttpEntity, Class, Map)spring-doc.cn

method(HttpMethod) .uri(String, Map) .headers(Consumer<HttpHeaders>) .body(Object) .retrieve() .toEntity(Class) [1]spring-doc.cn

exchange(URI, HttpMethod, HttpEntity, Class)spring-doc.cn

method(HttpMethod) .uri(URI) .headers(Consumer<HttpHeaders>) .body(Object) .retrieve() .toEntity(Class) [1]spring-doc.cn

exchange(String, HttpMethod, HttpEntity, ParameterizedTypeReference, Object…​)spring-doc.cn

method(HttpMethod) .uri(String, Object…​) .headers(Consumer<HttpHeaders>) .body(Object) .retrieve() .toEntity(ParameterizedTypeReference) [1]spring-doc.cn

exchange(String, HttpMethod, HttpEntity, ParameterizedTypeReference, Map)spring-doc.cn

method(HttpMethod) .uri(String, Map) .headers(Consumer<HttpHeaders>) .body(Object) .retrieve() .toEntity(ParameterizedTypeReference) [1]spring-doc.cn

exchange(URI, HttpMethod, HttpEntity, ParameterizedTypeReference)spring-doc.cn

method(HttpMethod) .uri(URI) .headers(Consumer<HttpHeaders>) .body(Object) .retrieve() .toEntity(ParameterizedTypeReference) [1]spring-doc.cn

exchange(RequestEntity, Class)spring-doc.cn

method(HttpMethod) .uri(URI) .headers(Consumer<HttpHeaders>) .body(Object) .retrieve() .toEntity(Class) [2]spring-doc.cn

exchange(RequestEntity, ParameterizedTypeReference)spring-doc.cn

method(HttpMethod) .uri(URI) .headers(Consumer<HttpHeaders>) .body(Object) .retrieve() .toEntity(ParameterizedTypeReference) [2]spring-doc.cn

execute(String, HttpMethod, RequestCallback, ResponseExtractor, Object…​)spring-doc.cn

method(HttpMethod) .uri(String, Object…​) .exchange(ExchangeFunction)spring-doc.cn

execute(String, HttpMethod, RequestCallback, ResponseExtractor, Map)spring-doc.cn

method(HttpMethod) .uri(String, Map) .exchange(ExchangeFunction)spring-doc.cn

execute(URI, HttpMethod, RequestCallback, ResponseExtractor)spring-doc.cn

method(HttpMethod) .uri(URI) .exchange(ExchangeFunction)spring-doc.cn

HTTP 接口

Spring Framework 允许您将 HTTP 服务定义为带有方法的 Java 接口。您可以将此类接口传递给 以创建通过 HTTP 客户端(如 或 )执行请求的代理。您还可以从 for server 实施接口 请求处理。@HttpExchangeHttpServiceProxyFactoryRestClientWebClient@Controllerspring-doc.cn

首先使用 methods 创建接口:@HttpExchangespring-doc.cn

interface RepositoryService {

	@GetExchange("/repos/{owner}/{repo}")
	Repository getRepository(@PathVariable String owner, @PathVariable String repo);

	// more HTTP exchange methods...

}

现在,您可以创建一个代理,在调用方法时执行请求。spring-doc.cn

为:RestClientspring-doc.cn

RestClient restClient = RestClient.builder().baseUrl("https://api.github.com/").build();
RestClientAdapter adapter = RestClientAdapter.create(restClient);
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();

RepositoryService service = factory.createClient(RepositoryService.class);

为:WebClientspring-doc.cn

WebClient webClient = WebClient.builder().baseUrl("https://api.github.com/").build();
WebClientAdapter adapter = WebClientAdapter.create(webClient);
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();

RepositoryService service = factory.createClient(RepositoryService.class);

为:RestTemplatespring-doc.cn

RestTemplate restTemplate = new RestTemplate();
restTemplate.setUriTemplateHandler(new DefaultUriBuilderFactory("https://api.github.com/"));
RestTemplateAdapter adapter = RestTemplateAdapter.create(restTemplate);
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();

RepositoryService service = factory.createClient(RepositoryService.class);

@HttpExchange在类型级别受支持,它适用于所有方法:spring-doc.cn

@HttpExchange(url = "/repos/{owner}/{repo}", accept = "application/vnd.github.v3+json")
interface RepositoryService {

	@GetExchange
	Repository getRepository(@PathVariable String owner, @PathVariable String repo);

	@PatchExchange(contentType = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
	void updateRepository(@PathVariable String owner, @PathVariable String repo,
			@RequestParam String name, @RequestParam String description, @RequestParam String homepage);

}

方法参数

带注释的 HTTP 交换方法支持灵活的方法签名,包括以下内容 方法参数:spring-doc.cn

Method 参数 描述

URIspring-doc.cn

动态设置请求的 URL,覆盖 annotation 的属性。urlspring-doc.cn

UriBuilderFactoryspring-doc.cn

提供 a 以扩展 URI 模板和 URI 变量。 实际上,替换了基础客户端的 (及其基本 URL) 。UriBuilderFactoryUriBuilderFactoryspring-doc.cn

HttpMethodspring-doc.cn

动态设置请求的 HTTP 方法,覆盖 Comments 的属性methodspring-doc.cn

@RequestHeaderspring-doc.cn

添加一个或多个请求标头。参数可以是 a 或具有多个标头、a of 值或 individual value 的非 String 值支持类型转换。这将覆盖 注解的属性。Map<String, ?>MultiValueMap<String, ?>Collection<?>headersspring-doc.cn

@PathVariablespring-doc.cn

在请求 URL 中添加用于扩展占位符的变量。参数可以是具有多个变量的 a,也可以是单个值。类型转换 支持非 String 值。Map<String, ?>spring-doc.cn

@RequestAttributespring-doc.cn

提供 to add 作为 request 属性。仅支持 和 。ObjectRestClientWebClientspring-doc.cn

@RequestBodyspring-doc.cn

将请求的主体作为要序列化的对象或 支持反应式流(如 、 或任何其他异步类型) 通过配置的 .PublisherMonoFluxReactiveAdapterRegistryspring-doc.cn

@RequestParamspring-doc.cn

添加一个或多个请求参数。参数可以是具有多个参数的 a 或、值 a 或 单个值。非 String 值支持类型转换。Map<String, ?>MultiValueMap<String, ?>Collection<?>spring-doc.cn

当设置为 , 请求 参数在请求正文中编码。否则,它们将被添加为 URL 查询 参数。"content-type""application/x-www-form-urlencoded"spring-doc.cn

@RequestPartspring-doc.cn

添加请求部分,可以是 String (表单字段)、(文件部分)、 对象(要编码的实体,例如,作为 JSON),(部分内容和标题), a Spring ,或上述任何一种的反应流。ResourceHttpEntityPartPublisherspring-doc.cn

MultipartFilespring-doc.cn

从 添加请求部分,通常用于 Spring MVC 控制器 其中,它表示上传的文件。MultipartFilespring-doc.cn

@CookieValuespring-doc.cn

添加一个或多个 Cookie。参数可以是 a 或包含多个 cookie、a of 值或 individual value 的非 String 值支持类型转换。Map<String, ?>MultiValueMap<String, ?>Collection<?>spring-doc.cn

方法参数不能是,除非属性(在 parameter 注释)设置为 ,或者参数标记为可选,由 MethodParameter#isOptional 确定。nullrequiredfalsespring-doc.cn

返回值

支持的返回值取决于底层客户端。spring-doc.cn

客户端适应 such as 并支持同步返回值:HttpExchangeAdapterRestClientRestTemplatespring-doc.cn

方法返回值 描述

voidspring-doc.cn

执行给定的请求。spring-doc.cn

HttpHeadersspring-doc.cn

执行给定的请求并返回响应标头。spring-doc.cn

<T>spring-doc.cn

执行给定的请求并将响应内容解码为声明的返回类型。spring-doc.cn

ResponseEntity<Void>spring-doc.cn

执行给定的请求并返回 a 以及 status 和 headers。ResponseEntityspring-doc.cn

ResponseEntity<T>spring-doc.cn

执行给定的请求,将响应内容解码为声明的返回类型,然后 返回 A 以及 status、Headers 和 Decoded 正文。ResponseEntityspring-doc.cn

客户端适应了例如 ,支持以上所有 以及反应式变体。下表显示了 Reactor 类型,但您也可以使用 通过 :ReactorHttpExchangeAdapterWebClientReactiveAdapterRegistryspring-doc.cn

方法返回值 描述

Mono<Void>spring-doc.cn

执行给定的请求,并发布响应内容(如果有)。spring-doc.cn

Mono<HttpHeaders>spring-doc.cn

执行给定的请求,释放响应内容(如果有),并返回 响应标头。spring-doc.cn

Mono<T>spring-doc.cn

执行给定的请求并将响应内容解码为声明的返回类型。spring-doc.cn

Flux<T>spring-doc.cn

执行给定的请求,并将响应内容解码为声明的 元素类型。spring-doc.cn

Mono<ResponseEntity<Void>>spring-doc.cn

执行给定的请求,并释放响应内容(如果有),并返回带有 status 和 headers 的 a。ResponseEntityspring-doc.cn

Mono<ResponseEntity<T>>spring-doc.cn

执行给定的请求,将响应内容解码为声明的返回类型,然后 返回 A 以及 status、Headers 和 Decoded 正文。ResponseEntityspring-doc.cn

Mono<ResponseEntity<Flux<T>>spring-doc.cn

执行给定的请求,将响应内容解码为声明的 元素类型,并返回带有 status、headers 和 decoded 的 响应正文流。ResponseEntityspring-doc.cn

默认情况下,同步返回值的超时取决于底层 HTTP 客户端的配置方式。您也可以在适配器级别上设置一个值,但我们建议依赖 底层 HTTP 客户端,它在较低级别运行并提供更多控制。ReactorHttpExchangeAdapterblockTimeoutspring-doc.cn

错误处理

要自定义错误响应处理,您需要配置底层 HTTP 客户端。spring-doc.cn

为:RestClientspring-doc.cn

默认情况下,引发 4xx 和 5xx HTTP 状态代码。 要自定义此功能,请注册适用于所有响应的响应状态处理程序 通过客户端执行:RestClientRestClientExceptionspring-doc.cn

RestClient restClient = RestClient.builder()
		.defaultStatusHandler(HttpStatusCode::isError, (request, response) -> ...)
		.build();

RestClientAdapter adapter = RestClientAdapter.create(restClient);
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();

有关更多详细信息和选项(例如禁止显示错误状态代码),请参阅 中的 Javadoc。defaultStatusHandlerRestClient.Builderspring-doc.cn

为:WebClientspring-doc.cn

默认情况下,引发 4xx 和 5xx HTTP 状态代码。 要自定义此功能,请注册适用于所有响应的响应状态处理程序 通过客户端执行:WebClientWebClientResponseExceptionspring-doc.cn

WebClient webClient = WebClient.builder()
		.defaultStatusHandler(HttpStatusCode::isError, resp -> ...)
		.build();

WebClientAdapter adapter = WebClientAdapter.create(webClient);
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(adapter).build();

有关更多详细信息和选项(例如禁止显示错误状态代码),请参阅 中的 Javadoc。defaultStatusHandlerWebClient.Builderspring-doc.cn

为:RestTemplatespring-doc.cn

默认情况下,引发 4xx 和 5xx HTTP 状态代码。 要自定义此设置,请注册一个适用于所有响应的错误处理程序 通过客户端执行:RestTemplateRestClientExceptionspring-doc.cn

RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(myErrorHandler);

RestTemplateAdapter adapter = RestTemplateAdapter.create(restTemplate);
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();

有关更多详细信息和选项,请参阅 in 和 层次结构。setErrorHandlerRestTemplateResponseErrorHandlerspring-doc.cn

Method 参数 描述

URIspring-doc.cn

动态设置请求的 URL,覆盖 annotation 的属性。urlspring-doc.cn

UriBuilderFactoryspring-doc.cn

提供 a 以扩展 URI 模板和 URI 变量。 实际上,替换了基础客户端的 (及其基本 URL) 。UriBuilderFactoryUriBuilderFactoryspring-doc.cn

HttpMethodspring-doc.cn

动态设置请求的 HTTP 方法,覆盖 Comments 的属性methodspring-doc.cn

@RequestHeaderspring-doc.cn

添加一个或多个请求标头。参数可以是 a 或具有多个标头、a of 值或 individual value 的非 String 值支持类型转换。这将覆盖 注解的属性。Map<String, ?>MultiValueMap<String, ?>Collection<?>headersspring-doc.cn

@PathVariablespring-doc.cn

在请求 URL 中添加用于扩展占位符的变量。参数可以是具有多个变量的 a,也可以是单个值。类型转换 支持非 String 值。Map<String, ?>spring-doc.cn

@RequestAttributespring-doc.cn

提供 to add 作为 request 属性。仅支持 和 。ObjectRestClientWebClientspring-doc.cn

@RequestBodyspring-doc.cn

将请求的主体作为要序列化的对象或 支持反应式流(如 、 或任何其他异步类型) 通过配置的 .PublisherMonoFluxReactiveAdapterRegistryspring-doc.cn

@RequestParamspring-doc.cn

添加一个或多个请求参数。参数可以是具有多个参数的 a 或、值 a 或 单个值。非 String 值支持类型转换。Map<String, ?>MultiValueMap<String, ?>Collection<?>spring-doc.cn

当设置为 , 请求 参数在请求正文中编码。否则,它们将被添加为 URL 查询 参数。"content-type""application/x-www-form-urlencoded"spring-doc.cn

@RequestPartspring-doc.cn

添加请求部分,可以是 String (表单字段)、(文件部分)、 对象(要编码的实体,例如,作为 JSON),(部分内容和标题), a Spring ,或上述任何一种的反应流。ResourceHttpEntityPartPublisherspring-doc.cn

MultipartFilespring-doc.cn

从 添加请求部分,通常用于 Spring MVC 控制器 其中,它表示上传的文件。MultipartFilespring-doc.cn

@CookieValuespring-doc.cn

添加一个或多个 Cookie。参数可以是 a 或包含多个 cookie、a of 值或 individual value 的非 String 值支持类型转换。Map<String, ?>MultiValueMap<String, ?>Collection<?>spring-doc.cn

方法返回值 描述

voidspring-doc.cn

执行给定的请求。spring-doc.cn

HttpHeadersspring-doc.cn

执行给定的请求并返回响应标头。spring-doc.cn

<T>spring-doc.cn

执行给定的请求并将响应内容解码为声明的返回类型。spring-doc.cn

ResponseEntity<Void>spring-doc.cn

执行给定的请求并返回 a 以及 status 和 headers。ResponseEntityspring-doc.cn

ResponseEntity<T>spring-doc.cn

执行给定的请求,将响应内容解码为声明的返回类型,然后 返回 A 以及 status、Headers 和 Decoded 正文。ResponseEntityspring-doc.cn

方法返回值 描述

Mono<Void>spring-doc.cn

执行给定的请求,并发布响应内容(如果有)。spring-doc.cn

Mono<HttpHeaders>spring-doc.cn

执行给定的请求,释放响应内容(如果有),并返回 响应标头。spring-doc.cn

Mono<T>spring-doc.cn

执行给定的请求并将响应内容解码为声明的返回类型。spring-doc.cn

Flux<T>spring-doc.cn

执行给定的请求,并将响应内容解码为声明的 元素类型。spring-doc.cn

Mono<ResponseEntity<Void>>spring-doc.cn

执行给定的请求,并释放响应内容(如果有),并返回带有 status 和 headers 的 a。ResponseEntityspring-doc.cn

Mono<ResponseEntity<T>>spring-doc.cn

执行给定的请求,将响应内容解码为声明的返回类型,然后 返回 A 以及 status、Headers 和 Decoded 正文。ResponseEntityspring-doc.cn

Mono<ResponseEntity<Flux<T>>spring-doc.cn

执行给定的请求,将响应内容解码为声明的 元素类型,并返回带有 status、headers 和 decoded 的 响应正文流。ResponseEntityspring-doc.cn


1. 接头和主体必须提供给 Via 和 .HttpEntityRestClientheaders(Consumer<HttpHeaders>)body(Object)
2. 方法、URI、标头和正文必须通过 、 和 提供给 。RequestEntityRestClientmethod(HttpMethod)uri(URI)headers(Consumer<HttpHeaders>)body(Object)