Rename 'spring.http.client' properties to 'spring.http.client.settings'
Build and Deploy Snapshot / Build and Deploy Snapshot (push) Waiting to run Details
Build and Deploy Snapshot / Trigger Docs Build (push) Blocked by required conditions Details
Build and Deploy Snapshot / Verify (push) Blocked by required conditions Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[early-access:true toolchain:true version:24], map[id:${{ vars.UBUNTU_MEDIUM || 'ubuntu-latest' }} name:Linux]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[early-access:true toolchain:true version:24], map[id:windows-latest name:Windows]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:false version:17], map[id:${{ vars.UBUNTU_MEDIUM || 'ubuntu-latest' }} name:Linux]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:false version:17], map[id:windows-latest name:Windows]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:false version:21], map[id:${{ vars.UBUNTU_MEDIUM || 'ubuntu-latest' }} name:Linux]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:false version:21], map[id:windows-latest name:Windows]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:false version:22], map[id:${{ vars.UBUNTU_MEDIUM || 'ubuntu-latest' }} name:Linux]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:false version:22], map[id:windows-latest name:Windows]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:true version:23], map[id:${{ vars.UBUNTU_MEDIUM || 'ubuntu-latest' }} name:Linux]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:true version:23], map[id:windows-latest name:Windows]) (push) Waiting to run Details
Run System Tests / Java ${{ matrix.java.version}} (map[toolchain:false version:17]) (push) Waiting to run Details
Run System Tests / Java ${{ matrix.java.version}} (map[toolchain:true version:21]) (push) Waiting to run Details

Deprecate 'spring.http.client' properties in favor of
'spring.http.client.settings` to align with the new reactive client
properties.

Closes gh-44958
This commit is contained in:
Phillip Webb 2025-04-10 07:13:13 -07:00
parent 068f621967
commit c69d3ef406
12 changed files with 299 additions and 81 deletions

View File

@ -18,12 +18,8 @@ package org.springframework.boot.autoconfigure.http.client;
import java.time.Duration;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.http.client.HttpClientSettings;
import org.springframework.boot.http.client.HttpRedirects;
import org.springframework.boot.ssl.SslBundle;
import org.springframework.boot.ssl.SslBundles;
import org.springframework.util.StringUtils;
/**
* Abstract base class for properties that directly or indirectly make use of a blocking
@ -38,7 +34,7 @@ public abstract class AbstractHttpClientProperties {
/**
* Handling for HTTP redirects.
*/
private HttpRedirects redirects = HttpRedirects.FOLLOW_WHEN_POSSIBLE;
private HttpRedirects redirects;
/**
* Default connect timeout for a client HTTP request.
@ -83,20 +79,6 @@ public abstract class AbstractHttpClientProperties {
return this.ssl;
}
/**
* Return {@link HttpClientSettings} based on these properties.
* @param sslBundles a {@link SslBundles} provider
* @return the {@link HttpClientSettings}
*/
protected HttpClientSettings httpClientSettings(ObjectProvider<SslBundles> sslBundles) {
return new HttpClientSettings(this.redirects, this.connectTimeout, this.readTimeout, sslBundle(sslBundles));
}
private SslBundle sslBundle(ObjectProvider<SslBundles> sslBundles) {
String name = getSsl().getBundle();
return (StringUtils.hasLength(name)) ? sslBundles.getObject().getBundle(name) : null;
}
/**
* SSL configuration.
*/

View File

@ -46,16 +46,6 @@ public abstract class AbstractHttpRequestFactoryProperties extends AbstractHttpC
this.factory = factory;
}
/**
* Return a {@link ClientHttpRequestFactoryBuilder} based on the properties.
* @param classLoader the class loader to use for detection
* @return a {@link ClientHttpRequestFactoryBuilder}
*/
protected final ClientHttpRequestFactoryBuilder<?> factoryBuilder(ClassLoader classLoader) {
Factory factory = getFactory();
return (factory != null) ? factory.builder() : ClientHttpRequestFactoryBuilder.detect(classLoader);
}
/**
* Supported factory types.
*/

View File

@ -0,0 +1,85 @@
/*
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.http.client;
import java.time.Duration;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Predicate;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.http.client.AbstractHttpClientProperties.Ssl;
import org.springframework.boot.autoconfigure.http.client.AbstractHttpRequestFactoryProperties.Factory;
import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder;
import org.springframework.boot.http.client.ClientHttpRequestFactorySettings;
import org.springframework.boot.http.client.ClientHttpRequestFactorySettings.Redirects;
import org.springframework.boot.http.client.HttpRedirects;
import org.springframework.boot.ssl.SslBundle;
import org.springframework.boot.ssl.SslBundles;
import org.springframework.util.StringUtils;
/**
* Helper class to create {@link ClientHttpRequestFactoryBuilder} and
* {@link ClientHttpRequestFactorySettings}.
*
* @author Phillip Webb
*/
class ClientHttpRequestFactories {
private final ObjectProvider<SslBundles> sslBundles;
private final AbstractHttpRequestFactoryProperties[] orderedProperties;
ClientHttpRequestFactories(ObjectProvider<SslBundles> sslBundles,
AbstractHttpRequestFactoryProperties... orderedProperties) {
this.sslBundles = sslBundles;
this.orderedProperties = orderedProperties;
}
ClientHttpRequestFactoryBuilder<?> builder(ClassLoader classLoader) {
Factory factory = getProperty(AbstractHttpRequestFactoryProperties::getFactory);
return (factory != null) ? factory.builder() : ClientHttpRequestFactoryBuilder.detect(classLoader);
}
ClientHttpRequestFactorySettings settings() {
HttpRedirects redirects = getProperty(AbstractHttpRequestFactoryProperties::getRedirects);
Duration connectTimeout = getProperty(AbstractHttpRequestFactoryProperties::getConnectTimeout);
Duration readTimeout = getProperty(AbstractHttpRequestFactoryProperties::getReadTimeout);
String sslBundleName = getProperty(AbstractHttpRequestFactoryProperties::getSsl, Ssl::getBundle,
StringUtils::hasLength);
SslBundle sslBundle = (StringUtils.hasLength(sslBundleName))
? this.sslBundles.getObject().getBundle(sslBundleName) : null;
return new ClientHttpRequestFactorySettings(Redirects.of(redirects), connectTimeout, readTimeout, sslBundle);
}
private <T> T getProperty(Function<AbstractHttpRequestFactoryProperties, T> accessor) {
return getProperty(accessor, Function.identity(), Objects::nonNull);
}
private <P, T> T getProperty(Function<AbstractHttpRequestFactoryProperties, P> accessor, Function<P, T> extractor,
Predicate<T> predicate) {
for (AbstractHttpRequestFactoryProperties properties : this.orderedProperties) {
P value = accessor.apply(properties);
T extracted = (value != null) ? extractor.apply(value) : null;
if (predicate.test(extracted)) {
return extracted;
}
}
return null;
}
}

View File

@ -28,9 +28,6 @@ import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder;
import org.springframework.boot.http.client.ClientHttpRequestFactorySettings;
import org.springframework.boot.http.client.ClientHttpRequestFactorySettings.Redirects;
import org.springframework.boot.http.client.HttpClientSettings;
import org.springframework.boot.http.client.HttpRedirects;
import org.springframework.boot.ssl.SslBundles;
import org.springframework.boot.util.LambdaSafe;
import org.springframework.context.annotation.Bean;
@ -44,14 +41,22 @@ import org.springframework.http.client.ClientHttpRequestFactory;
* @author Phillip Webb
* @since 3.4.0
*/
@SuppressWarnings("removal")
@AutoConfiguration(after = SslAutoConfiguration.class)
@ConditionalOnClass(ClientHttpRequestFactory.class)
@Conditional(NotReactiveWebApplicationCondition.class)
@EnableConfigurationProperties(HttpClientProperties.class)
@EnableConfigurationProperties({ HttpClientSettingsProperties.class, HttpClientProperties.class })
public class HttpClientAutoConfiguration implements BeanClassLoaderAware {
private final ClientHttpRequestFactories factories;
private ClassLoader beanClassLoader;
HttpClientAutoConfiguration(ObjectProvider<SslBundles> sslBundles, HttpClientSettingsProperties properties,
HttpClientProperties deprecatedProperties) {
this.factories = new ClientHttpRequestFactories(sslBundles, properties, deprecatedProperties);
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.beanClassLoader = classLoader;
@ -59,9 +64,9 @@ public class HttpClientAutoConfiguration implements BeanClassLoaderAware {
@Bean
@ConditionalOnMissingBean
ClientHttpRequestFactoryBuilder<?> clientHttpRequestFactoryBuilder(HttpClientProperties httpClientProperties,
ClientHttpRequestFactoryBuilder<?> clientHttpRequestFactoryBuilder(
ObjectProvider<ClientHttpRequestFactoryBuilderCustomizer<?>> clientHttpRequestFactoryBuilderCustomizers) {
ClientHttpRequestFactoryBuilder<?> builder = httpClientProperties.factoryBuilder(this.beanClassLoader);
ClientHttpRequestFactoryBuilder<?> builder = this.factories.builder(this.beanClassLoader);
return customize(builder, clientHttpRequestFactoryBuilderCustomizers.orderedStream().toList());
}
@ -76,19 +81,8 @@ public class HttpClientAutoConfiguration implements BeanClassLoaderAware {
@Bean
@ConditionalOnMissingBean
ClientHttpRequestFactorySettings clientHttpRequestFactorySettings(HttpClientProperties httpClientProperties,
ObjectProvider<SslBundles> sslBundles) {
HttpClientSettings settings = httpClientProperties.httpClientSettings(sslBundles);
return new ClientHttpRequestFactorySettings(asRequestFactoryRedirects(settings.redirects()),
settings.connectTimeout(), settings.readTimeout(), settings.sslBundle());
}
private Redirects asRequestFactoryRedirects(HttpRedirects redirects) {
return switch (redirects) {
case FOLLOW_WHEN_POSSIBLE -> Redirects.FOLLOW_WHEN_POSSIBLE;
case FOLLOW -> Redirects.FOLLOW;
case DONT_FOLLOW -> Redirects.DONT_FOLLOW;
};
ClientHttpRequestFactorySettings clientHttpRequestFactorySettings() {
return this.factories.settings();
}
}

View File

@ -16,8 +16,12 @@
package org.springframework.boot.autoconfigure.http.client;
import java.time.Duration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
import org.springframework.boot.http.client.ClientHttpRequestFactorySettings;
import org.springframework.boot.http.client.HttpRedirects;
/**
* {@link ConfigurationProperties @ConfigurationProperties} for a Spring's blocking HTTP
@ -26,8 +30,41 @@ import org.springframework.boot.http.client.ClientHttpRequestFactorySettings;
* @author Phillip Webb
* @since 3.4.0
* @see ClientHttpRequestFactorySettings
* @deprecated since 3.5.0 for removal in 4.0.0 in favor of
* {@link HttpClientSettingsProperties}
*/
@ConfigurationProperties("spring.http.client")
@Deprecated(since = "3.5.0", forRemoval = true)
public class HttpClientProperties extends AbstractHttpRequestFactoryProperties {
@Override
@DeprecatedConfigurationProperty(since = "3.5.0", replacement = "spring.http.client.settings.factory")
public Factory getFactory() {
return super.getFactory();
}
@Override
@DeprecatedConfigurationProperty(since = "3.5.0", replacement = "spring.http.client.settings.redirects")
public HttpRedirects getRedirects() {
return super.getRedirects();
}
@Override
@DeprecatedConfigurationProperty(since = "3.5.0", replacement = "spring.http.client.settings.connect-timeout")
public Duration getConnectTimeout() {
return super.getConnectTimeout();
}
@Override
@DeprecatedConfigurationProperty(since = "3.5.0", replacement = "spring.http.client.settings.read-timeout")
public Duration getReadTimeout() {
return super.getReadTimeout();
}
@Override
@DeprecatedConfigurationProperty(since = "3.5.0", replacement = "spring.http.client.settings.ssl")
public Ssl getSsl() {
return super.getSsl();
}
}

View File

@ -0,0 +1,33 @@
/*
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.http.client;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.http.client.reactive.ClientHttpConnectorSettings;
/**
* {@link ConfigurationProperties @ConfigurationProperties} to configure settings that
* apply to Spring's reactive client HTTP connectors.
*
* @author Phillip Webb
* @since 3.5.0
* @see ClientHttpConnectorSettings
*/
@ConfigurationProperties("spring.http.client.settings")
public class HttpClientSettingsProperties extends AbstractHttpRequestFactoryProperties {
}

View File

@ -18,13 +18,10 @@ package org.springframework.boot.autoconfigure.http.client.reactive;
import java.util.function.Supplier;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.http.client.AbstractHttpClientProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.http.client.HttpClientSettings;
import org.springframework.boot.http.client.reactive.ClientHttpConnectorBuilder;
import org.springframework.boot.http.client.reactive.ClientHttpConnectorSettings;
import org.springframework.boot.ssl.SslBundles;
import org.springframework.http.client.reactive.ClientHttpConnector;
/**
@ -50,21 +47,6 @@ public abstract class AbstractClientHttpConnectorProperties extends AbstractHttp
this.connector = connector;
}
@Override
protected HttpClientSettings httpClientSettings(ObjectProvider<SslBundles> sslBundles) {
return super.httpClientSettings(sslBundles);
}
/**
* Return a {@link ClientHttpConnectorBuilder} based on the properties.
* @param classLoader the class loader to use for detection
* @return a {@link ClientHttpConnectorBuilder}
*/
protected final ClientHttpConnectorBuilder<?> connectorBuilder(ClassLoader classLoader) {
Connector connector = getConnector();
return (connector != null) ? connector.builder() : ClientHttpConnectorBuilder.detect(classLoader);
}
/**
* Supported factory types.
*/

View File

@ -29,7 +29,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.reactor.netty.ReactorNettyConfigurations;
import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.http.client.HttpClientSettings;
import org.springframework.boot.http.client.reactive.ClientHttpConnectorBuilder;
import org.springframework.boot.http.client.reactive.ClientHttpConnectorSettings;
import org.springframework.boot.ssl.SslBundles;
@ -52,8 +51,15 @@ import org.springframework.http.client.reactive.ClientHttpConnector;
@EnableConfigurationProperties(HttpReactiveClientSettingsProperties.class)
public class ClientHttpConnectorAutoConfiguration implements BeanClassLoaderAware {
private final ClientHttpConnectors connectors;
private ClassLoader beanClassLoader;
ClientHttpConnectorAutoConfiguration(ObjectProvider<SslBundles> sslBundles,
HttpReactiveClientSettingsProperties properties) {
this.connectors = new ClientHttpConnectors(sslBundles, properties);
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.beanClassLoader = classLoader;
@ -62,10 +68,8 @@ public class ClientHttpConnectorAutoConfiguration implements BeanClassLoaderAwar
@Bean
@ConditionalOnMissingBean
ClientHttpConnectorBuilder<?> clientHttpConnectorBuilder(
HttpReactiveClientSettingsProperties httpReactiveClientSettingsProperties,
ObjectProvider<ClientHttpConnectorBuilderCustomizer<?>> clientHttpConnectorBuilderCustomizers) {
ClientHttpConnectorBuilder<?> builder = httpReactiveClientSettingsProperties
.connectorBuilder(this.beanClassLoader);
ClientHttpConnectorBuilder<?> builder = this.connectors.builder(this.beanClassLoader);
return customize(builder, clientHttpConnectorBuilderCustomizers.orderedStream().toList());
}
@ -80,12 +84,8 @@ public class ClientHttpConnectorAutoConfiguration implements BeanClassLoaderAwar
@Bean
@ConditionalOnMissingBean
ClientHttpConnectorSettings clientHttpConnectorSettings(
HttpReactiveClientSettingsProperties httpReactiveClientSettingsProperties,
ObjectProvider<SslBundles> sslBundles) {
HttpClientSettings settings = httpReactiveClientSettingsProperties.httpClientSettings(sslBundles);
return new ClientHttpConnectorSettings(settings.redirects(), settings.connectTimeout(), settings.readTimeout(),
settings.sslBundle());
ClientHttpConnectorSettings clientHttpConnectorSettings() {
return this.connectors.settings();
}
@Bean

View File

@ -0,0 +1,84 @@
/*
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.http.client.reactive;
import java.time.Duration;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Predicate;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.http.client.AbstractHttpClientProperties.Ssl;
import org.springframework.boot.autoconfigure.http.client.reactive.AbstractClientHttpConnectorProperties.Connector;
import org.springframework.boot.http.client.HttpRedirects;
import org.springframework.boot.http.client.reactive.ClientHttpConnectorBuilder;
import org.springframework.boot.http.client.reactive.ClientHttpConnectorSettings;
import org.springframework.boot.ssl.SslBundle;
import org.springframework.boot.ssl.SslBundles;
import org.springframework.util.StringUtils;
/**
* Helper class to create {@link ClientHttpConnectorBuilder} and
* {@link ClientHttpConnectorSettings}.
*
* @author Phillip Webb
*/
class ClientHttpConnectors {
private final ObjectProvider<SslBundles> sslBundles;
private final AbstractClientHttpConnectorProperties[] orderedProperties;
ClientHttpConnectors(ObjectProvider<SslBundles> sslBundles,
AbstractClientHttpConnectorProperties... orderedProperties) {
this.sslBundles = sslBundles;
this.orderedProperties = orderedProperties;
}
ClientHttpConnectorBuilder<?> builder(ClassLoader classLoader) {
Connector connector = getProperty(AbstractClientHttpConnectorProperties::getConnector);
return (connector != null) ? connector.builder() : ClientHttpConnectorBuilder.detect(classLoader);
}
ClientHttpConnectorSettings settings() {
HttpRedirects redirects = getProperty(AbstractClientHttpConnectorProperties::getRedirects);
Duration connectTimeout = getProperty(AbstractClientHttpConnectorProperties::getConnectTimeout);
Duration readTimeout = getProperty(AbstractClientHttpConnectorProperties::getReadTimeout);
String sslBundleName = getProperty(AbstractClientHttpConnectorProperties::getSsl, Ssl::getBundle,
StringUtils::hasText);
SslBundle sslBundle = (StringUtils.hasLength(sslBundleName))
? this.sslBundles.getObject().getBundle(sslBundleName) : null;
return new ClientHttpConnectorSettings(redirects, connectTimeout, readTimeout, sslBundle);
}
private <T> T getProperty(Function<AbstractClientHttpConnectorProperties, T> accessor) {
return getProperty(accessor, Function.identity(), Objects::nonNull);
}
private <P, T> T getProperty(Function<AbstractClientHttpConnectorProperties, P> accessor, Function<P, T> extractor,
Predicate<T> predicate) {
for (AbstractClientHttpConnectorProperties properties : this.orderedProperties) {
P value = accessor.apply(properties);
T extracted = (value != null) ? extractor.apply(value) : null;
if (predicate.test(extracted)) {
return extracted;
}
}
return null;
}
}

View File

@ -68,6 +68,21 @@ class HttpClientAutoConfigurationTests {
@Test
void configuresClientHttpRequestFactorySettings() {
this.contextRunner.withPropertyValues(sslPropertyValues().toArray(String[]::new))
.withPropertyValues("spring.http.client.settings.redirects=dont-follow",
"spring.http.client.settings.connect-timeout=10s", "spring.http.client.settings.read-timeout=20s",
"spring.http.client.settings.ssl.bundle=test")
.run((context) -> {
ClientHttpRequestFactorySettings settings = context.getBean(ClientHttpRequestFactorySettings.class);
assertThat(settings.redirects()).isEqualTo(Redirects.DONT_FOLLOW);
assertThat(settings.connectTimeout()).isEqualTo(Duration.ofSeconds(10));
assertThat(settings.readTimeout()).isEqualTo(Duration.ofSeconds(20));
assertThat(settings.sslBundle().getKey().getAlias()).isEqualTo("alias1");
});
}
@Test
void configuresClientHttpRequestFactorySettingsUsingDeprecatedProperties() {
this.contextRunner.withPropertyValues(sslPropertyValues().toArray(String[]::new))
.withPropertyValues("spring.http.client.redirects=dont-follow", "spring.http.client.connect-timeout=10s",
"spring.http.client.read-timeout=20s", "spring.http.client.ssl.bundle=test")

View File

@ -248,7 +248,7 @@ If multiple clients are available on the classpath, and not global configuration
[[io.rest-client.clienthttprequestfactory.configuration]]
=== Global HTTP Client Configuration
If the auto-detected HTTP client does not meet your needs, you can use the configprop:spring.http.client.factory[] property to pick a specific factory.
If the auto-detected HTTP client does not meet your needs, you can use the configprop:spring.http.client.settings.factory[] property to pick a specific factory.
For example, if you have Apache HttpClient on your classpath, but you prefer Jetty's javadoc:org.eclipse.jetty.client.HttpClient[] you can add the following:
[configprops,yaml]
@ -256,7 +256,8 @@ For example, if you have Apache HttpClient on your classpath, but you prefer Jet
spring:
http:
client:
factory: jetty
settings:
factory: jetty
----
You can also set properties to change defaults that will be applied to all clients.
@ -267,9 +268,10 @@ For example, you may want to change timeouts and if redirects are followed:
spring:
http:
client:
connect-timeout: 2s
read-timeout: 1s
redirects: dont-follow
settings:
connect-timeout: 2s
read-timeout: 1s
redirects: dont-follow
----
For more complex customizations, you can use javadoc:org.springframework.boot.autoconfigure.http.client.ClientHttpRequestFactoryBuilderCustomizer[] or declare your own javadoc:org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder[] bean which will cause auto-configuration to back off.

View File

@ -145,6 +145,20 @@ public record ClientHttpRequestFactorySettings(Redirects redirects, Duration con
return this.httpClientRedirects;
}
/**
* Return the related {@link Redirects} for the given {@link HttpRedirects}.
* @param httpRedirects the HTTP redirects
* @return the related redirects
* @since 3.5.0
*/
public static Redirects of(HttpRedirects httpRedirects) {
return (httpRedirects != null) ? switch (httpRedirects) {
case FOLLOW_WHEN_POSSIBLE -> FOLLOW_WHEN_POSSIBLE;
case FOLLOW -> FOLLOW;
case DONT_FOLLOW -> DONT_FOLLOW;
} : null;
}
}
}