diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/TestRestTemplate.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/TestRestTemplate.java index f571a1d973..c3c69d8759 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/TestRestTemplate.java +++ b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/TestRestTemplate.java @@ -46,7 +46,7 @@ import org.apache.hc.core5.http.ssl.TLS; import org.apache.hc.core5.ssl.SSLContextBuilder; import org.apache.hc.core5.ssl.TrustStrategy; -import org.springframework.boot.web.client.ClientHttpRequestFactorySettings; +import org.springframework.boot.http.client.ClientHttpRequestFactorySettings; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.boot.web.client.RootUriTemplateHandler; import org.springframework.core.ParameterizedTypeReference; @@ -146,7 +146,7 @@ public class TestRestTemplate { if (httpClientOptions != null) { ClientHttpRequestFactory requestFactory = builder.buildRequestFactory(); if (requestFactory instanceof HttpComponentsClientHttpRequestFactory) { - builder = builder.requestFactory( + builder = builder.requestFactoryBuilder( (settings) -> new CustomHttpComponentsClientHttpRequestFactory(httpClientOptions, settings)); } } @@ -1007,6 +1007,26 @@ public class TestRestTemplate { private final boolean enableRedirects; + /** + * Create a new {@link CustomHttpComponentsClientHttpRequestFactory} instance. + * @param httpClientOptions the {@link HttpClient} options + * @param settings the settings to apply + * @deprecated since 3.4.0 for removal in 3.6.0 in favor of + * {@link #CustomHttpComponentsClientHttpRequestFactory(HttpClientOption[], ClientHttpRequestFactorySettings)} + */ + @Deprecated(since = "3.4.0", forRemoval = true) + @SuppressWarnings("removal") + public CustomHttpComponentsClientHttpRequestFactory(HttpClientOption[] httpClientOptions, + org.springframework.boot.web.client.ClientHttpRequestFactorySettings settings) { + this(httpClientOptions, new ClientHttpRequestFactorySettings(settings.connectTimeout(), + settings.readTimeout(), settings.sslBundle())); + } + + /** + * Create a new {@link CustomHttpComponentsClientHttpRequestFactory} instance. + * @param httpClientOptions the {@link HttpClient} options + * @param settings the settings to apply + */ public CustomHttpComponentsClientHttpRequestFactory(HttpClientOption[] httpClientOptions, ClientHttpRequestFactorySettings settings) { Set options = new HashSet<>(Arrays.asList(httpClientOptions)); diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/RestTemplateBuilder.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/RestTemplateBuilder.java index f3b7aa9c73..b3daff38ea 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/RestTemplateBuilder.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/RestTemplateBuilder.java @@ -31,6 +31,8 @@ import java.util.function.Function; import java.util.function.Supplier; import org.springframework.beans.BeanUtils; +import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder; +import org.springframework.boot.http.client.ClientHttpRequestFactorySettings; import org.springframework.boot.ssl.SslBundle; import org.springframework.http.client.ClientHttpRequest; import org.springframework.http.client.ClientHttpRequestFactory; @@ -76,7 +78,7 @@ public class RestTemplateBuilder { private final Set interceptors; - private final Function requestFactory; + private final ClientHttpRequestFactoryBuilder requestFactoryBuilder; private final UriTemplateHandler uriTemplateHandler; @@ -97,12 +99,12 @@ public class RestTemplateBuilder { */ public RestTemplateBuilder(RestTemplateCustomizer... customizers) { Assert.notNull(customizers, "Customizers must not be null"); - this.requestFactorySettings = ClientHttpRequestFactorySettings.DEFAULTS; + this.requestFactorySettings = ClientHttpRequestFactorySettings.defaults(); this.detectRequestFactory = true; this.rootUri = null; this.messageConverters = null; this.interceptors = Collections.emptySet(); - this.requestFactory = null; + this.requestFactoryBuilder = null; this.uriTemplateHandler = null; this.errorHandler = null; this.basicAuthentication = null; @@ -113,8 +115,7 @@ public class RestTemplateBuilder { private RestTemplateBuilder(ClientHttpRequestFactorySettings requestFactorySettings, boolean detectRequestFactory, String rootUri, Set> messageConverters, - Set interceptors, - Function requestFactory, + Set interceptors, ClientHttpRequestFactoryBuilder requestFactoryBuilder, UriTemplateHandler uriTemplateHandler, ResponseErrorHandler errorHandler, BasicAuthentication basicAuthentication, Map> defaultHeaders, Set customizers, Set> requestCustomizers) { @@ -123,7 +124,7 @@ public class RestTemplateBuilder { this.rootUri = rootUri; this.messageConverters = messageConverters; this.interceptors = interceptors; - this.requestFactory = requestFactory; + this.requestFactoryBuilder = requestFactoryBuilder; this.uriTemplateHandler = uriTemplateHandler; this.errorHandler = errorHandler; this.basicAuthentication = basicAuthentication; @@ -141,7 +142,7 @@ public class RestTemplateBuilder { */ public RestTemplateBuilder detectRequestFactory(boolean detectRequestFactory) { return new RestTemplateBuilder(this.requestFactorySettings, detectRequestFactory, this.rootUri, - this.messageConverters, this.interceptors, this.requestFactory, this.uriTemplateHandler, + this.messageConverters, this.interceptors, this.requestFactoryBuilder, this.uriTemplateHandler, this.errorHandler, this.basicAuthentication, this.defaultHeaders, this.customizers, this.requestCustomizers); } @@ -155,7 +156,7 @@ public class RestTemplateBuilder { */ public RestTemplateBuilder rootUri(String rootUri) { return new RestTemplateBuilder(this.requestFactorySettings, this.detectRequestFactory, rootUri, - this.messageConverters, this.interceptors, this.requestFactory, this.uriTemplateHandler, + this.messageConverters, this.interceptors, this.requestFactoryBuilder, this.uriTemplateHandler, this.errorHandler, this.basicAuthentication, this.defaultHeaders, this.customizers, this.requestCustomizers); } @@ -186,7 +187,7 @@ public class RestTemplateBuilder { public RestTemplateBuilder messageConverters(Collection> messageConverters) { Assert.notNull(messageConverters, "MessageConverters must not be null"); return new RestTemplateBuilder(this.requestFactorySettings, this.detectRequestFactory, this.rootUri, - copiedSetOf(messageConverters), this.interceptors, this.requestFactory, this.uriTemplateHandler, + copiedSetOf(messageConverters), this.interceptors, this.requestFactoryBuilder, this.uriTemplateHandler, this.errorHandler, this.basicAuthentication, this.defaultHeaders, this.customizers, this.requestCustomizers); } @@ -216,7 +217,7 @@ public class RestTemplateBuilder { Collection> messageConverters) { Assert.notNull(messageConverters, "MessageConverters must not be null"); return new RestTemplateBuilder(this.requestFactorySettings, this.detectRequestFactory, this.rootUri, - append(this.messageConverters, messageConverters), this.interceptors, this.requestFactory, + append(this.messageConverters, messageConverters), this.interceptors, this.requestFactoryBuilder, this.uriTemplateHandler, this.errorHandler, this.basicAuthentication, this.defaultHeaders, this.customizers, this.requestCustomizers); } @@ -230,7 +231,7 @@ public class RestTemplateBuilder { */ public RestTemplateBuilder defaultMessageConverters() { return new RestTemplateBuilder(this.requestFactorySettings, this.detectRequestFactory, this.rootUri, - copiedSetOf(new RestTemplate().getMessageConverters()), this.interceptors, this.requestFactory, + copiedSetOf(new RestTemplate().getMessageConverters()), this.interceptors, this.requestFactoryBuilder, this.uriTemplateHandler, this.errorHandler, this.basicAuthentication, this.defaultHeaders, this.customizers, this.requestCustomizers); } @@ -261,7 +262,7 @@ public class RestTemplateBuilder { public RestTemplateBuilder interceptors(Collection interceptors) { Assert.notNull(interceptors, "interceptors must not be null"); return new RestTemplateBuilder(this.requestFactorySettings, this.detectRequestFactory, this.rootUri, - this.messageConverters, copiedSetOf(interceptors), this.requestFactory, this.uriTemplateHandler, + this.messageConverters, copiedSetOf(interceptors), this.requestFactoryBuilder, this.uriTemplateHandler, this.errorHandler, this.basicAuthentication, this.defaultHeaders, this.customizers, this.requestCustomizers); } @@ -290,7 +291,7 @@ public class RestTemplateBuilder { public RestTemplateBuilder additionalInterceptors(Collection interceptors) { Assert.notNull(interceptors, "interceptors must not be null"); return new RestTemplateBuilder(this.requestFactorySettings, this.detectRequestFactory, this.rootUri, - this.messageConverters, append(this.interceptors, interceptors), this.requestFactory, + this.messageConverters, append(this.interceptors, interceptors), this.requestFactoryBuilder, this.uriTemplateHandler, this.errorHandler, this.basicAuthentication, this.defaultHeaders, this.customizers, this.requestCustomizers); } @@ -300,10 +301,12 @@ public class RestTemplateBuilder { * {@link RestTemplate}. * @param requestFactoryType the request factory type to use * @return a new builder instance + * @see ClientHttpRequestFactoryBuilder#of(Class) + * @see #requestFactoryBuilder(ClientHttpRequestFactoryBuilder) */ public RestTemplateBuilder requestFactory(Class requestFactoryType) { Assert.notNull(requestFactoryType, "RequestFactoryType must not be null"); - return requestFactory((settings) -> ClientHttpRequestFactories.get(requestFactoryType, settings)); + return requestFactoryBuilder(ClientHttpRequestFactoryBuilder.of(requestFactoryType)); } /** @@ -312,10 +315,12 @@ public class RestTemplateBuilder { * @param requestFactorySupplier the supplier for the request factory * @return a new builder instance * @since 2.0.0 + * @see ClientHttpRequestFactoryBuilder#of(Supplier) + * @see #requestFactoryBuilder(ClientHttpRequestFactoryBuilder) */ public RestTemplateBuilder requestFactory(Supplier requestFactorySupplier) { Assert.notNull(requestFactorySupplier, "RequestFactorySupplier must not be null"); - return requestFactory((settings) -> ClientHttpRequestFactories.get(requestFactorySupplier, settings)); + return requestFactoryBuilder(ClientHttpRequestFactoryBuilder.of(requestFactorySupplier)); } /** @@ -325,13 +330,28 @@ public class RestTemplateBuilder { * @param requestFactoryFunction the settings to request factory function * @return a new builder instance * @since 3.0.0 - * @see ClientHttpRequestFactories + * @see ClientHttpRequestFactoryBuilder + * @see #requestFactoryBuilder(ClientHttpRequestFactoryBuilder) */ public RestTemplateBuilder requestFactory( - Function requestFactoryFunction) { + Function requestFactoryFunction) { Assert.notNull(requestFactoryFunction, "RequestFactoryFunction must not be null"); + return requestFactoryBuilder((settings) -> requestFactoryFunction + .apply(org.springframework.boot.web.client.ClientHttpRequestFactorySettings.of(settings))); + } + + /** + * Set the {@link ClientHttpRequestFactoryBuilder} that should be used each time we + * {@link #build()} a new {@link RestTemplate} instance. + * @param requestFactoryBuilder the {@link ClientHttpRequestFactoryBuilder} to use + * @return a new builder instance + * @since 3.4.0 + * @see ClientHttpRequestFactoryBuilder + */ + public RestTemplateBuilder requestFactoryBuilder(ClientHttpRequestFactoryBuilder requestFactoryBuilder) { + Assert.notNull(requestFactoryBuilder, "ClientHttpRequestFactoryBuilder must not be null"); return new RestTemplateBuilder(this.requestFactorySettings, this.detectRequestFactory, this.rootUri, - this.messageConverters, this.interceptors, requestFactoryFunction, this.uriTemplateHandler, + this.messageConverters, this.interceptors, requestFactoryBuilder, this.uriTemplateHandler, this.errorHandler, this.basicAuthentication, this.defaultHeaders, this.customizers, this.requestCustomizers); } @@ -345,8 +365,9 @@ public class RestTemplateBuilder { public RestTemplateBuilder uriTemplateHandler(UriTemplateHandler uriTemplateHandler) { Assert.notNull(uriTemplateHandler, "UriTemplateHandler must not be null"); return new RestTemplateBuilder(this.requestFactorySettings, this.detectRequestFactory, this.rootUri, - this.messageConverters, this.interceptors, this.requestFactory, uriTemplateHandler, this.errorHandler, - this.basicAuthentication, this.defaultHeaders, this.customizers, this.requestCustomizers); + this.messageConverters, this.interceptors, this.requestFactoryBuilder, uriTemplateHandler, + this.errorHandler, this.basicAuthentication, this.defaultHeaders, this.customizers, + this.requestCustomizers); } /** @@ -358,8 +379,8 @@ public class RestTemplateBuilder { public RestTemplateBuilder errorHandler(ResponseErrorHandler errorHandler) { Assert.notNull(errorHandler, "ErrorHandler must not be null"); return new RestTemplateBuilder(this.requestFactorySettings, this.detectRequestFactory, this.rootUri, - this.messageConverters, this.interceptors, this.requestFactory, this.uriTemplateHandler, errorHandler, - this.basicAuthentication, this.defaultHeaders, this.customizers, this.requestCustomizers); + this.messageConverters, this.interceptors, this.requestFactoryBuilder, this.uriTemplateHandler, + errorHandler, this.basicAuthentication, this.defaultHeaders, this.customizers, this.requestCustomizers); } /** @@ -386,7 +407,7 @@ public class RestTemplateBuilder { */ public RestTemplateBuilder basicAuthentication(String username, String password, Charset charset) { return new RestTemplateBuilder(this.requestFactorySettings, this.detectRequestFactory, this.rootUri, - this.messageConverters, this.interceptors, this.requestFactory, this.uriTemplateHandler, + this.messageConverters, this.interceptors, this.requestFactoryBuilder, this.uriTemplateHandler, this.errorHandler, new BasicAuthentication(username, password, charset), this.defaultHeaders, this.customizers, this.requestCustomizers); } @@ -403,7 +424,7 @@ public class RestTemplateBuilder { Assert.notNull(name, "Name must not be null"); Assert.notNull(values, "Values must not be null"); return new RestTemplateBuilder(this.requestFactorySettings, this.detectRequestFactory, this.rootUri, - this.messageConverters, this.interceptors, this.requestFactory, this.uriTemplateHandler, + this.messageConverters, this.interceptors, this.requestFactoryBuilder, this.uriTemplateHandler, this.errorHandler, this.basicAuthentication, append(this.defaultHeaders, name, values), this.customizers, this.requestCustomizers); } @@ -429,9 +450,9 @@ public class RestTemplateBuilder { */ public RestTemplateBuilder connectTimeout(Duration connectTimeout) { return new RestTemplateBuilder(this.requestFactorySettings.withConnectTimeout(connectTimeout), - this.detectRequestFactory, this.rootUri, this.messageConverters, this.interceptors, this.requestFactory, - this.uriTemplateHandler, this.errorHandler, this.basicAuthentication, this.defaultHeaders, - this.customizers, this.requestCustomizers); + this.detectRequestFactory, this.rootUri, this.messageConverters, this.interceptors, + this.requestFactoryBuilder, this.uriTemplateHandler, this.errorHandler, this.basicAuthentication, + this.defaultHeaders, this.customizers, this.requestCustomizers); } /** @@ -455,9 +476,9 @@ public class RestTemplateBuilder { */ public RestTemplateBuilder readTimeout(Duration readTimeout) { return new RestTemplateBuilder(this.requestFactorySettings.withReadTimeout(readTimeout), - this.detectRequestFactory, this.rootUri, this.messageConverters, this.interceptors, this.requestFactory, - this.uriTemplateHandler, this.errorHandler, this.basicAuthentication, this.defaultHeaders, - this.customizers, this.requestCustomizers); + this.detectRequestFactory, this.rootUri, this.messageConverters, this.interceptors, + this.requestFactoryBuilder, this.uriTemplateHandler, this.errorHandler, this.basicAuthentication, + this.defaultHeaders, this.customizers, this.requestCustomizers); } /** @@ -481,9 +502,9 @@ public class RestTemplateBuilder { */ public RestTemplateBuilder sslBundle(SslBundle sslBundle) { return new RestTemplateBuilder(this.requestFactorySettings.withSslBundle(sslBundle), this.detectRequestFactory, - this.rootUri, this.messageConverters, this.interceptors, this.requestFactory, this.uriTemplateHandler, - this.errorHandler, this.basicAuthentication, this.defaultHeaders, this.customizers, - this.requestCustomizers); + this.rootUri, this.messageConverters, this.interceptors, this.requestFactoryBuilder, + this.uriTemplateHandler, this.errorHandler, this.basicAuthentication, this.defaultHeaders, + this.customizers, this.requestCustomizers); } /** @@ -512,7 +533,7 @@ public class RestTemplateBuilder { public RestTemplateBuilder customizers(Collection customizers) { Assert.notNull(customizers, "Customizers must not be null"); return new RestTemplateBuilder(this.requestFactorySettings, this.detectRequestFactory, this.rootUri, - this.messageConverters, this.interceptors, this.requestFactory, this.uriTemplateHandler, + this.messageConverters, this.interceptors, this.requestFactoryBuilder, this.uriTemplateHandler, this.errorHandler, this.basicAuthentication, this.defaultHeaders, copiedSetOf(customizers), this.requestCustomizers); } @@ -541,7 +562,7 @@ public class RestTemplateBuilder { public RestTemplateBuilder additionalCustomizers(Collection customizers) { Assert.notNull(customizers, "RestTemplateCustomizers must not be null"); return new RestTemplateBuilder(this.requestFactorySettings, this.detectRequestFactory, this.rootUri, - this.messageConverters, this.interceptors, this.requestFactory, this.uriTemplateHandler, + this.messageConverters, this.interceptors, this.requestFactoryBuilder, this.uriTemplateHandler, this.errorHandler, this.basicAuthentication, this.defaultHeaders, append(this.customizers, customizers), this.requestCustomizers); } @@ -575,7 +596,7 @@ public class RestTemplateBuilder { Collection> requestCustomizers) { Assert.notNull(requestCustomizers, "RequestCustomizers must not be null"); return new RestTemplateBuilder(this.requestFactorySettings, this.detectRequestFactory, this.rootUri, - this.messageConverters, this.interceptors, this.requestFactory, this.uriTemplateHandler, + this.messageConverters, this.interceptors, this.requestFactoryBuilder, this.uriTemplateHandler, this.errorHandler, this.basicAuthentication, this.defaultHeaders, this.customizers, copiedSetOf(requestCustomizers)); } @@ -607,7 +628,7 @@ public class RestTemplateBuilder { Collection> requestCustomizers) { Assert.notNull(requestCustomizers, "RequestCustomizers must not be null"); return new RestTemplateBuilder(this.requestFactorySettings, this.detectRequestFactory, this.rootUri, - this.messageConverters, this.interceptors, this.requestFactory, this.uriTemplateHandler, + this.messageConverters, this.interceptors, this.requestFactoryBuilder, this.uriTemplateHandler, this.errorHandler, this.basicAuthentication, this.defaultHeaders, this.customizers, append(this.requestCustomizers, requestCustomizers)); } @@ -677,11 +698,11 @@ public class RestTemplateBuilder { * @since 2.2.0 */ public ClientHttpRequestFactory buildRequestFactory() { - if (this.requestFactory != null) { - return this.requestFactory.apply(this.requestFactorySettings); + if (this.requestFactoryBuilder != null) { + return this.requestFactoryBuilder.build(this.requestFactorySettings); } if (this.detectRequestFactory) { - return ClientHttpRequestFactories.get(this.requestFactorySettings); + return ClientHttpRequestFactoryBuilder.detect().build(this.requestFactorySettings); } return null; }