调用 REST 服务
Spring Boot 提供了多种便捷方式用于调用远程 REST 服务。
如果你正在开发非阻塞的响应式应用,并且使用 Spring WebFlux,则可以使用 WebClient
。
如果你更倾向于阻塞式 API,则可以使用 RestClient
或 RestTemplate
。
WebClient
如果你的 classpath 上有 Spring WebFlux,推荐使用 WebClient
调用远程 REST 服务。
WebClient
接口提供了函数式风格 API,并且完全响应式。
你可以在专门的 Spring Framework 文档 WebClient 部分 了解更多。
如果你不是在编写响应式 Spring WebFlux 应用,可以使用 RestClient 替代 WebClient 。
这提供了类似的函数式 API,但为阻塞式而非响应式。
|
Spring Boot 会为你创建并预配置一个原型 WebClient.Builder
bean。
强烈建议在你的组件中注入它,并用来创建 WebClient
实例。
Spring Boot 配置该 builder 以共享 HTTP 资源,并以与服务器相同的方式反映 codecs 设置(参见 WebFlux HTTP codecs 自动配置),以及更多。
以下代码展示了一个典型示例:
-
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 上可用的库自动检测用于驱动 WebClient
的 ClientHttpConnector
。
优先顺序如下,支持以下客户端:
-
Reactor Netty
-
Jetty RS client
-
Apache HttpClient
-
JDK HttpClient
如果 classpath 上有多个客户端,将使用优先级最高的客户端。
spring-boot-starter-webflux
starter 默认依赖 io.projectreactor.netty:reactor-netty
,它同时带来服务器和客户端实现。
如果你选择使用 Jetty 作为响应式服务器,则应添加 Jetty Reactive HTTP client 库依赖 org.eclipse.jetty:jetty-reactive-httpclient
。
客户端和服务器使用同一技术有优势,因为会自动在客户端和服务器之间共享 HTTP 资源。
开发者可以通过提供自定义 ReactorResourceFactory
或 JettyResourceFactory
bean 覆盖 Jetty 和 Reactor Netty 的资源配置——这会同时应用于客户端和服务器。
如果你希望为客户端覆盖该选择,可以定义自己的 ClientHttpConnector
bean,并完全控制客户端配置。
你可以在 Spring Framework 参考文档 WebClient 配置选项
了解更多。
全局 HTTP Connector 配置
如果自动检测到的 ClientHttpConnector
不能满足你的需求,可以使用 spring.http.reactiveclient.connector
属性选择特定 connector。
例如,如果你的 classpath 上有 Reactor Netty,但更喜欢 Jetty 的 HttpClient
,可以添加如下配置:
-
Properties
-
YAML
spring.http.reactiveclient.connector=jetty
spring:
http:
reactiveclient:
connector: jetty
你还可以设置属性以更改所有响应式 connector 的默认值。 例如,你可能希望更改超时时间以及是否跟随重定向:
-
Properties
-
YAML
spring.http.reactiveclient.connect-timeout=2s
spring.http.reactiveclient.read-timeout=1s
spring.http.reactiveclient.redirects=dont-follow
spring:
http:
reactiveclient:
connect-timeout: 2s
read-timeout: 1s
redirects: dont-follow
对于更复杂的定制,可以使用 ClientHttpConnectorBuilderCustomizer
,或声明你自己的 ClientHttpConnectorBuilder
bean,这将导致自动配置失效。
当你需要定制底层 HTTP 库的一些内部细节时,这很有用。
例如,以下配置将使用带有特定 ProxySelector
的 JDK 客户端:
-
Java
-
Kotlin
import java.net.ProxySelector;
import org.springframework.boot.http.client.reactive.ClientHttpConnectorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyConnectorHttpConfiguration {
@Bean
ClientHttpConnectorBuilder<?> clientHttpConnectorBuilder(ProxySelector proxySelector) {
return ClientHttpConnectorBuilder.jdk().withHttpClientCustomizer((builder) -> builder.proxy(proxySelector));
}
}
import org.springframework.boot.http.client.reactive.ClientHttpConnectorBuilder;
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import java.net.ProxySelector
import java.net.http.HttpClient
@Configuration(proxyBeanMethods = false)
class MyConnectorHttpConfiguration {
@Bean
fun clientHttpConnectorBuilder(proxySelector: ProxySelector): ClientHttpConnectorBuilder<*> {
return ClientHttpConnectorBuilder.jdk().withHttpClientCustomizer { builder -> builder.proxy(proxySelector) }
}
}
WebClient 定制
WebClient
定制有三种主要方式,取决于你希望定制的范围。
若希望定制范围尽可能窄,注入自动配置的 WebClient.Builder
,然后按需调用其方法。
WebClient.Builder
实例是有状态的:对 builder 的任何更改都会反映到随后用它创建的所有客户端。
如果你想用同一个 builder 创建多个客户端,也可以通过 WebClient.Builder other = builder.clone();
克隆 builder。
若希望对所有 WebClient.Builder
实例进行应用级别的增量定制,可以声明 WebClientCustomizer
bean,并在注入点本地更改 WebClient.Builder
。
最后,你可以回退到原始 API,直接使用 WebClient.create()
。
此时不会应用自动配置或 WebClientCustomizer
。
WebClient SSL 支持
如果你需要对 WebClient
使用的 ClientHttpConnector
进行自定义 SSL 配置,可以注入 WebClientSsl
实例,并结合 builder 的 apply
方法使用。
WebClientSsl
接口可访问你在 application.properties
或 application.yaml
文件中定义的任意 SSL bundles。
以下代码展示了一个典型示例:
-
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)
}
}
RestClient
如果你的应用未使用 Spring WebFlux 或 Project Reactor,推荐使用 RestClient
调用远程 REST 服务。
RestClient
接口提供了函数式风格的阻塞式 API。
Spring Boot 会为你创建并预配置一个原型 RestClient.Builder
bean。
强烈建议在你的组件中注入它,并用来创建 RestClient
实例。
Spring Boot 会用 HttpMessageConverters
和合适的 ClientHttpRequestFactory
配置该 builder。
以下代码展示了一个典型示例:
-
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
定制有三种主要方式,取决于你希望定制的范围。
若希望定制范围尽可能窄,注入自动配置的 RestClient.Builder
,然后按需调用其方法。
RestClient.Builder
实例是有状态的:对 builder 的任何更改都会反映到随后用它创建的所有客户端。
如果你想用同一个 builder 创建多个客户端,也可以通过 RestClient.Builder other = builder.clone();
克隆 builder。
若希望对所有 RestClient.Builder
实例进行应用级别的增量定制,可以声明 RestClientCustomizer
bean,并在注入点本地更改 RestClient.Builder
。
最后,你可以回退到原始 API,直接使用 RestClient.create()
。
此时不会应用自动配置或 RestClientCustomizer
。
你也可以更改 全局 HTTP 客户端配置。 |
RestClient SSL 支持
如果你需要对 RestClient
使用的 ClientHttpRequestFactory
进行自定义 SSL 配置,可以注入 RestClientSsl
实例,并结合 builder 的 apply
方法使用。
RestClientSsl
接口可访问你在 application.properties
或 application.yaml
文件中定义的任意 SSL bundles。
以下代码展示了一个典型示例:
-
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 bundle 还需要应用其他定制,可以结合 ClientHttpRequestFactorySettings
与 ClientHttpRequestFactoryBuilder
使用:
-
Java
-
Kotlin
import java.time.Duration;
import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder;
import org.springframework.boot.http.client.ClientHttpRequestFactorySettings;
import org.springframework.boot.ssl.SslBundles;
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
.ofSslBundle(sslBundles.getBundle("mybundle"))
.withReadTimeout(Duration.ofMinutes(2));
ClientHttpRequestFactory requestFactory = ClientHttpRequestFactoryBuilder.detect().build(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.http.client.ClientHttpRequestFactoryBuilder;
import org.springframework.boot.http.client.ClientHttpRequestFactorySettings;
import org.springframework.boot.ssl.SslBundles
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 = ClientHttpRequestFactoryBuilder.detect().build(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 的 RestTemplate
类早于 RestClient
,是许多应用调用远程 REST 服务的经典方式。
当你有现有代码不想迁移到 RestClient
,或已熟悉 RestTemplate
API 时,可以选择使用 RestTemplate
。
由于 RestTemplate
实例通常需要在使用前定制,Spring Boot 不会提供任何单一自动配置的 RestTemplate
bean。
但会自动配置一个 RestTemplateBuilder
,可用于按需创建 RestTemplate
实例。
自动配置的 RestTemplateBuilder
确保为 RestTemplate
实例应用合理的 HttpMessageConverters
和合适的 ClientHttpRequestFactory
。
以下代码展示了一个典型示例:
-
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
包含许多有用方法,可快速配置 RestTemplate
。
例如,添加 BASIC 认证支持可使用 builder.basicAuthentication("user", "password").build()
。
RestTemplate 定制
RestTemplate
定制有三种主要方式,取决于你希望定制的范围。
若希望定制范围尽可能窄,注入自动配置的 RestTemplateBuilder
,然后按需调用其方法。
每次方法调用都会返回一个新的 RestTemplateBuilder
实例,因此定制仅影响本次 builder 的使用。
若希望进行应用级别的增量定制,可使用 RestTemplateCustomizer
bean。
所有此类 bean 会自动注册到自动配置的 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)
}
}
}
最后,你可以定义自己的 RestTemplateBuilder
bean。
这样会替换自动配置的 builder。
如果你希望像自动配置一样应用所有 RestTemplateCustomizer
bean,可使用 RestTemplateBuilderConfigurer
进行配置。
以下示例暴露了一个与 Spring Boot 自动配置一致但指定了自定义连接和读取超时的 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())
.connectTimeout(Duration.ofSeconds(5))
.readTimeout(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()).connectTimeout(Duration.ofSeconds(5))
.readTimeout(Duration.ofSeconds(2))
}
}
最极端(且很少用)的方式是创建自己的 RestTemplateBuilder
bean 而不使用 configurer。
这不仅会替换自动配置的 builder,还会阻止任何 RestTemplateCustomizer
bean 被使用。
你也可以更改 全局 HTTP 客户端配置。 |
RestTemplate SSL 支持
如果你需要对 RestTemplate
进行自定义 SSL 配置,可以如本例所示将 SSL bundle 应用于 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.sslBundle(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.sslBundle(sslBundles.getBundle("mybundle")).build()
}
fun someRestCall(name: String): Details {
return restTemplate.getForObject("/{name}/details", Details::class.java, name)!!
}
}
RestClient 和 RestTemplate 的 HTTP 客户端检测
Spring Boot 会根据应用 classpath 上可用的库自动检测用于 RestClient
和 RestTemplate
的 HTTP 客户端。
优先顺序如下,支持以下客户端:
-
Apache HttpClient
-
Jetty HttpClient
-
Reactor Netty HttpClient
-
JDK client (
java.net.http.HttpClient
) -
Simple JDK client (
java.net.HttpURLConnection
)
如果 classpath 上有多个客户端,且未提供全局配置,将使用优先级最高的客户端。
全局 HTTP 客户端配置
如果自动检测到的 HTTP 客户端不能满足你的需求,可以使用 spring.http.client.factory
属性选择特定 factory。
例如,如果你的 classpath 上有 Apache HttpClient,但更喜欢 Jetty 的 HttpClient
,可以添加如下配置:
-
Properties
-
YAML
spring.http.client.factory=jetty
spring:
http:
client:
factory: jetty
你还可以设置属性以更改所有客户端的默认值。 例如,你可能希望更改超时时间以及是否跟随重定向:
-
Properties
-
YAML
spring.http.client.connect-timeout=2s
spring.http.client.read-timeout=1s
spring.http.client.redirects=dont-follow
spring:
http:
client:
connect-timeout: 2s
read-timeout: 1s
redirects: dont-follow
对于更复杂的定制,可以使用 ClientHttpRequestFactoryBuilderCustomizer
,或声明你自己的 ClientHttpRequestFactoryBuilder
bean,这将导致自动配置失效。
当你需要定制底层 HTTP 库的一些内部细节时,这很有用。
例如,以下配置将使用带有特定 ProxySelector
的 JDK 客户端:
-
Java
-
Kotlin
import java.net.ProxySelector;
import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyClientHttpConfiguration {
@Bean
ClientHttpRequestFactoryBuilder<?> clientHttpRequestFactoryBuilder(ProxySelector proxySelector) {
return ClientHttpRequestFactoryBuilder.jdk()
.withHttpClientCustomizer((builder) -> builder.proxy(proxySelector));
}
}
import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import java.net.ProxySelector
import java.net.http.HttpClient
@Configuration(proxyBeanMethods = false)
class MyClientHttpConfiguration {
@Bean
fun clientHttpRequestFactoryBuilder(proxySelector: ProxySelector): ClientHttpRequestFactoryBuilder<*> {
return ClientHttpRequestFactoryBuilder.jdk()
.withHttpClientCustomizer { builder -> builder.proxy(proxySelector) }
}
}