此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Boot 3.3.4! |
此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Boot 3.3.4! |
Spring Boot 提供了多种便捷的方法来调用远程 REST 服务。
如果您正在开发一个非阻塞响应式应用程序并且您正在使用 Spring WebFlux,那么您可以使用 .
如果您更喜欢阻止 API,则可以使用 或 。WebClient
RestClient
RestTemplate
Web客户端
如果你的 Classpath 上有 Spring WebFlux,我们建议你使用 来调用远程 REST 服务。
该接口提供了一个函数式的 API,并且是完全响应式的。
您可以在 Spring Framework 文档的专用部分中了解更多信息。WebClient
WebClient
WebClient
如果您不是编写反应式 Spring WebFlux 应用程序,则可以使用 RestClient 而不是 .
这提供了类似的功能 API,但 this is blocking instead reactor 。WebClient |
Spring Boot 为您创建并预配置原型 bean。
强烈建议将其注入到您的组件中并使用它来创建实例。
Spring Boot 正在配置该构建器以共享 HTTP 资源并以与服务器相同的方式反映编解码器设置(参见 WebFlux HTTP 编解码器自动配置)等等。WebClient.Builder
WebClient
以下代码显示了一个典型的示例:
-
Java
-
Kotlin
import reactor.core.publisher.Mono;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
@Service
public class MyService {
private final WebClient webClient;
public MyService(WebClient.Builder webClientBuilder) {
this.webClient = webClientBuilder.baseUrl("https://example.org").build();
}
public Mono<Details> someRestCall(String name) {
return this.webClient.get().uri("/{name}/details", name).retrieve().bodyToMono(Details.class);
}
}
import org.springframework.stereotype.Service
import org.springframework.web.reactive.function.client.WebClient
import reactor.core.publisher.Mono
@Service
class MyService(webClientBuilder: WebClient.Builder) {
private val webClient: WebClient
init {
webClient = webClientBuilder.baseUrl("https://example.org").build()
}
fun someRestCall(name: String?): Mono<Details> {
return webClient.get().uri("/{name}/details", name)
.retrieve().bodyToMono(Details::class.java)
}
}
WebClient 运行时
Spring Boot 将根据应用程序 Classpath 上可用的库自动检测使用哪个来驱动。
按优先顺序,支持以下客户端:ClientHttpConnector
WebClient
-
Reactor Netty
-
Jetty RS 客户端
-
Apache HttpClient
-
JDK HttpClient
如果 Classpath 上有多个 Client 端可用,则将使用最首选的 Client 端。
starter 依赖于 by default,它带来了 server 和 client 实现。
如果您选择使用 Jetty 作为反应式服务器,则应添加对 Jetty 反应式 HTTP 客户端库的依赖项。
对服务器和客户端使用相同的技术有其优势,因为它会自动在客户端和服务器之间共享 HTTP 资源。spring-boot-starter-webflux
io.projectreactor.netty:reactor-netty
org.eclipse.jetty:jetty-reactive-httpclient
开发人员可以通过提供自定义或 bean 来覆盖 Jetty 和 Reactor Netty 的资源配置——这将应用于客户端和服务器。ReactorResourceFactory
JettyResourceFactory
如果您希望为 Client 端覆盖该选择,则可以定义自己的 Bean 并完全控制 Client 端配置。ClientHttpConnector
您可以在 Spring Framework 参考文档中了解有关 WebClient
配置选项的更多信息。
WebClient 自定义
自定义有三种主要方法,具体取决于您希望自定义应用的范围。WebClient
要使任何自定义的范围尽可能窄,请注入 auto-configured,然后根据需要调用其方法。 实例是有状态的:生成器上的任何更改都会反映在随后使用它创建的所有客户端中。
如果要使用同一生成器创建多个客户端,还可以考虑使用 克隆生成器。WebClient.Builder
WebClient.Builder
WebClient.Builder other = builder.clone();
要对所有实例进行应用程序范围的附加自定义,您可以声明 bean 并在注入点本地更改 。WebClient.Builder
WebClientCustomizer
WebClient.Builder
最后,您可以回退到原始 API 并使用 .
在这种情况下,不会应用任何自动配置 or。WebClient.create()
WebClientCustomizer
WebClient SSL 支持
如果您需要 上使用的自定义 SSL 配置,则可以注入一个可与构建器方法一起使用的实例。ClientHttpConnector
WebClient
WebClientSsl
apply
该接口提供对您在 or 文件中定义的任何 SSL 捆绑包的访问。WebClientSsl
application.properties
application.yaml
以下代码显示了一个典型的示例:
-
Java
-
Kotlin
import reactor.core.publisher.Mono;
import org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientSsl;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
@Service
public class MyService {
private final WebClient webClient;
public MyService(WebClient.Builder webClientBuilder, WebClientSsl ssl) {
this.webClient = webClientBuilder.baseUrl("https://example.org").apply(ssl.fromBundle("mybundle")).build();
}
public Mono<Details> someRestCall(String name) {
return this.webClient.get().uri("/{name}/details", name).retrieve().bodyToMono(Details.class);
}
}
import org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientSsl
import org.springframework.stereotype.Service
import org.springframework.web.reactive.function.client.WebClient
import reactor.core.publisher.Mono
@Service
class MyService(webClientBuilder: WebClient.Builder, ssl: WebClientSsl) {
private val webClient: WebClient
init {
webClient = webClientBuilder.baseUrl("https://example.org")
.apply(ssl.fromBundle("mybundle")).build()
}
fun someRestCall(name: String?): Mono<Details> {
return webClient.get().uri("/{name}/details", name)
.retrieve().bodyToMono(Details::class.java)
}
}
如果您不是编写反应式 Spring WebFlux 应用程序,则可以使用 RestClient 而不是 .
这提供了类似的功能 API,但 this is blocking instead reactor 。WebClient |
Rest客户端
如果您没有在应用程序中使用 Spring WebFlux 或 Project Reactor,我们建议您使用 来调用远程 REST 服务。RestClient
该接口提供了一个功能式的阻塞 API。RestClient
Spring Boot 为您创建并预配置原型 bean。
强烈建议将其注入到您的组件中并使用它来创建实例。
Spring Boot 正在使用适当的 .RestClient.Builder
RestClient
HttpMessageConverters
ClientHttpRequestFactory
以下代码显示了一个典型的示例:
-
Java
-
Kotlin
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClient;
@Service
public class MyService {
private final RestClient restClient;
public MyService(RestClient.Builder restClientBuilder) {
this.restClient = restClientBuilder.baseUrl("https://example.org").build();
}
public Details someRestCall(String name) {
return this.restClient.get().uri("/{name}/details", name).retrieve().body(Details.class);
}
}
import org.springframework.boot.docs.io.restclient.restclient.ssl.Details
import org.springframework.stereotype.Service
import org.springframework.web.client.RestClient
@Service
class MyService(restClientBuilder: RestClient.Builder) {
private val restClient: RestClient
init {
restClient = restClientBuilder.baseUrl("https://example.org").build()
}
fun someRestCall(name: String?): Details {
return restClient.get().uri("/{name}/details", name)
.retrieve().body(Details::class.java)!!
}
}
RestClient 自定义
自定义有三种主要方法,具体取决于您希望自定义应用的范围。RestClient
要使任何自定义的范围尽可能窄,请注入 auto-configured,然后根据需要调用其方法。 实例是有状态的:生成器上的任何更改都会反映在随后使用它创建的所有客户端中。
如果要使用同一生成器创建多个客户端,还可以考虑使用 克隆生成器。RestClient.Builder
RestClient.Builder
RestClient.Builder other = builder.clone();
要对所有实例进行应用程序范围的附加自定义,您可以声明 bean 并在注入点本地更改 。RestClient.Builder
RestClientCustomizer
RestClient.Builder
最后,您可以回退到原始 API 并使用 .
在这种情况下,不会应用任何自动配置 or。RestClient.create()
RestClientCustomizer
RestClient SSL 支持
如果您需要 上使用的自定义 SSL 配置,则可以注入一个可与构建器方法一起使用的实例。ClientHttpRequestFactory
RestClient
RestClientSsl
apply
该接口提供对您在 or 文件中定义的任何 SSL 捆绑包的访问。RestClientSsl
application.properties
application.yaml
以下代码显示了一个典型的示例:
-
Java
-
Kotlin
import org.springframework.boot.autoconfigure.web.client.RestClientSsl;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClient;
@Service
public class MyService {
private final RestClient restClient;
public MyService(RestClient.Builder restClientBuilder, RestClientSsl ssl) {
this.restClient = restClientBuilder.baseUrl("https://example.org").apply(ssl.fromBundle("mybundle")).build();
}
public Details someRestCall(String name) {
return this.restClient.get().uri("/{name}/details", name).retrieve().body(Details.class);
}
}
import org.springframework.boot.autoconfigure.web.client.RestClientSsl
import org.springframework.boot.docs.io.restclient.restclient.ssl.settings.Details
import org.springframework.stereotype.Service
import org.springframework.web.client.RestClient
@Service
class MyService(restClientBuilder: RestClient.Builder, ssl: RestClientSsl) {
private val restClient: RestClient
init {
restClient = restClientBuilder.baseUrl("https://example.org")
.apply(ssl.fromBundle("mybundle")).build()
}
fun someRestCall(name: String?): Details {
return restClient.get().uri("/{name}/details", name)
.retrieve().body(Details::class.java)!!
}
}
如果除了 SSL 捆绑包之外还需要应用其他自定义,则可以将类与:ClientHttpRequestFactorySettings
ClientHttpRequestFactories
-
Java
-
Kotlin
import java.time.Duration;
import org.springframework.boot.ssl.SslBundles;
import org.springframework.boot.web.client.ClientHttpRequestFactories;
import org.springframework.boot.web.client.ClientHttpRequestFactorySettings;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClient;
@Service
public class MyService {
private final RestClient restClient;
public MyService(RestClient.Builder restClientBuilder, SslBundles sslBundles) {
ClientHttpRequestFactorySettings settings = ClientHttpRequestFactorySettings.DEFAULTS
.withReadTimeout(Duration.ofMinutes(2))
.withSslBundle(sslBundles.getBundle("mybundle"));
ClientHttpRequestFactory requestFactory = ClientHttpRequestFactories.get(settings);
this.restClient = restClientBuilder.baseUrl("https://example.org").requestFactory(requestFactory).build();
}
public Details someRestCall(String name) {
return this.restClient.get().uri("/{name}/details", name).retrieve().body(Details.class);
}
}
import org.springframework.boot.ssl.SslBundles
import org.springframework.boot.web.client.ClientHttpRequestFactories
import org.springframework.boot.web.client.ClientHttpRequestFactorySettings
import org.springframework.stereotype.Service
import org.springframework.web.client.RestClient
import java.time.Duration
@Service
class MyService(restClientBuilder: RestClient.Builder, sslBundles: SslBundles) {
private val restClient: RestClient
init {
val settings = ClientHttpRequestFactorySettings.DEFAULTS
.withReadTimeout(Duration.ofMinutes(2))
.withSslBundle(sslBundles.getBundle("mybundle"))
val requestFactory = ClientHttpRequestFactories.get(settings)
restClient = restClientBuilder
.baseUrl("https://example.org")
.requestFactory(requestFactory).build()
}
fun someRestCall(name: String?): Details {
return restClient.get().uri("/{name}/details", name).retrieve().body(Details::class.java)!!
}
}
RestTemplate (休息模板)
Spring Framework 的类早于许多应用程序用来调用远程 REST 服务的经典方式。
当您有不想迁移到 的现有代码时,或者因为您已经熟悉 API,您可以选择使用。RestTemplate
RestClient
RestTemplate
RestClient
RestTemplate
由于实例通常需要在使用之前进行自定义,因此 Spring Boot 不提供任何单个自动配置的 bean。
但是,它会自动配置 ,该 可用于在需要时创建实例。
auto-configured 确保将 sensible 和 appropriate 应用于实例。RestTemplate
RestTemplate
RestTemplateBuilder
RestTemplate
RestTemplateBuilder
HttpMessageConverters
ClientHttpRequestFactory
RestTemplate
以下代码显示了一个典型的示例:
-
Java
-
Kotlin
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class MyService {
private final RestTemplate restTemplate;
public MyService(RestTemplateBuilder restTemplateBuilder) {
this.restTemplate = restTemplateBuilder.build();
}
public Details someRestCall(String name) {
return this.restTemplate.getForObject("/{name}/details", Details.class, name);
}
}
import org.springframework.boot.web.client.RestTemplateBuilder
import org.springframework.stereotype.Service
import org.springframework.web.client.RestTemplate
@Service
class MyService(restTemplateBuilder: RestTemplateBuilder) {
private val restTemplate: RestTemplate
init {
restTemplate = restTemplateBuilder.build()
}
fun someRestCall(name: String): Details {
return restTemplate.getForObject("/{name}/details", Details::class.java, name)!!
}
}
RestTemplateBuilder
包括许多有用的方法,可用于快速配置 .
例如,要添加 BASIC 身份验证支持,您可以使用 .RestTemplate
builder.basicAuthentication("user", "password").build()
RestTemplate 自定义
自定义有三种主要方法,具体取决于您希望自定义应用的范围。RestTemplate
要使任何自定义的范围尽可能窄,请注入 auto-configured,然后根据需要调用其方法。
每个方法调用都会返回一个新实例,因此自定义项仅影响生成器的这种使用。RestTemplateBuilder
RestTemplateBuilder
要进行应用程序范围的附加定制,请使用 Bean。
所有这些 bean 都会自动注册到自动配置的 bean 中,并应用于使用它构建的任何模板。RestTemplateCustomizer
RestTemplateBuilder
以下示例显示了一个定制器,该定制器为除以下主机之外的所有主机配置代理的使用:192.168.0.5
-
Java
-
Kotlin
import org.apache.hc.client5.http.classic.HttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.client5.http.impl.routing.DefaultProxyRoutePlanner;
import org.apache.hc.client5.http.routing.HttpRoutePlanner;
import org.apache.hc.core5.http.HttpException;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.springframework.boot.web.client.RestTemplateCustomizer;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
public class MyRestTemplateCustomizer implements RestTemplateCustomizer {
@Override
public void customize(RestTemplate restTemplate) {
HttpRoutePlanner routePlanner = new CustomRoutePlanner(new HttpHost("proxy.example.com"));
HttpClient httpClient = HttpClientBuilder.create().setRoutePlanner(routePlanner).build();
restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory(httpClient));
}
static class CustomRoutePlanner extends DefaultProxyRoutePlanner {
CustomRoutePlanner(HttpHost proxy) {
super(proxy);
}
@Override
protected HttpHost determineProxy(HttpHost target, HttpContext context) throws HttpException {
if (target.getHostName().equals("192.168.0.5")) {
return null;
}
return super.determineProxy(target, context);
}
}
}
import org.apache.hc.client5.http.classic.HttpClient
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder
import org.apache.hc.client5.http.impl.routing.DefaultProxyRoutePlanner
import org.apache.hc.client5.http.routing.HttpRoutePlanner
import org.apache.hc.core5.http.HttpException
import org.apache.hc.core5.http.HttpHost
import org.apache.hc.core5.http.protocol.HttpContext
import org.springframework.boot.web.client.RestTemplateCustomizer
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory
import org.springframework.web.client.RestTemplate
class MyRestTemplateCustomizer : RestTemplateCustomizer {
override fun customize(restTemplate: RestTemplate) {
val routePlanner: HttpRoutePlanner = CustomRoutePlanner(HttpHost("proxy.example.com"))
val httpClient: HttpClient = HttpClientBuilder.create().setRoutePlanner(routePlanner).build()
restTemplate.requestFactory = HttpComponentsClientHttpRequestFactory(httpClient)
}
internal class CustomRoutePlanner(proxy: HttpHost?) : DefaultProxyRoutePlanner(proxy) {
@Throws(HttpException::class)
public override fun determineProxy(target: HttpHost, context: HttpContext): HttpHost? {
if (target.hostName == "192.168.0.5") {
return null
}
return super.determineProxy(target, context)
}
}
}
最后,您可以定义自己的 Bean。
这样做将替换自动配置的生成器。
如果您希望将任何 bean 应用于自定义构建器,就像自动配置所做的那样,请使用 .
下面的示例公开了一个与 Spring Boot 的自动配置相匹配的操作,只是还指定了自定义连接和读取超时:RestTemplateBuilder
RestTemplateCustomizer
RestTemplateBuilderConfigurer
RestTemplateBuilder
-
Java
-
Kotlin
import java.time.Duration;
import org.springframework.boot.autoconfigure.web.client.RestTemplateBuilderConfigurer;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyRestTemplateBuilderConfiguration {
@Bean
public RestTemplateBuilder restTemplateBuilder(RestTemplateBuilderConfigurer configurer) {
return configurer.configure(new RestTemplateBuilder())
.setConnectTimeout(Duration.ofSeconds(5))
.setReadTimeout(Duration.ofSeconds(2));
}
}
import org.springframework.boot.autoconfigure.web.client.RestTemplateBuilderConfigurer
import org.springframework.boot.web.client.RestTemplateBuilder
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import java.time.Duration
@Configuration(proxyBeanMethods = false)
class MyRestTemplateBuilderConfiguration {
@Bean
fun restTemplateBuilder(configurer: RestTemplateBuilderConfigurer): RestTemplateBuilder {
return configurer.configure(RestTemplateBuilder()).setConnectTimeout(Duration.ofSeconds(5))
.setReadTimeout(Duration.ofSeconds(2))
}
}
最极端(也很少使用)的选项是在不使用配置器的情况下创建自己的 bean。
除了替换自动配置的构建器之外,这还会阻止使用任何 bean。RestTemplateBuilder
RestTemplateCustomizer
RestTemplate SSL 支持
如果需要在 上自定义 SSL 配置,则可以将 SSL 捆绑包应用于 ,如以下示例所示:RestTemplate
RestTemplateBuilder
-
Java
-
Kotlin
import org.springframework.boot.docs.io.restclient.resttemplate.Details;
import org.springframework.boot.ssl.SslBundles;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class MyService {
private final RestTemplate restTemplate;
public MyService(RestTemplateBuilder restTemplateBuilder, SslBundles sslBundles) {
this.restTemplate = restTemplateBuilder.setSslBundle(sslBundles.getBundle("mybundle")).build();
}
public Details someRestCall(String name) {
return this.restTemplate.getForObject("/{name}/details", Details.class, name);
}
}
import org.springframework.boot.docs.io.restclient.resttemplate.Details
import org.springframework.boot.ssl.SslBundles
import org.springframework.boot.web.client.RestTemplateBuilder
import org.springframework.stereotype.Service
import org.springframework.web.client.RestTemplate
@Service
class MyService(restTemplateBuilder: RestTemplateBuilder, sslBundles: SslBundles) {
private val restTemplate: RestTemplate
init {
restTemplate = restTemplateBuilder.setSslBundle(sslBundles.getBundle("mybundle")).build()
}
fun someRestCall(name: String): Details {
return restTemplate.getForObject("/{name}/details", Details::class.java, name)!!
}
}
RestClient 和 RestTemplate 的 HTTP 客户端检测
Spring Boot 将自动检测要使用的 HTTP 客户端,并取决于应用程序 Classpath 上可用的库。
按优先顺序,支持以下客户端:RestClient
RestTemplate
-
Apache HttpClient
-
Jetty HttpClient
-
OkHttp (已弃用)
-
简单 JDK 客户端 (
HttpURLConnection
)
如果 Classpath 上有多个 Client 端可用,则将使用最首选的 Client 端。