From ca3a0b19d634948703e442eda732785b5120e0a6 Mon Sep 17 00:00:00 2001 From: Rob Winch Date: Tue, 20 Aug 2019 10:45:23 -0500 Subject: [PATCH] DefaultWebClientBuilder defaults using classpath Previously DefaultWebClientBuilder always defaulted the ClientHttpConnector with ReactorClientHttpConnector. This worked fine if reactor was used. However, it would break if the user was trying to leverage Jetty. This commit defaults to use Reactory Netty HttpClient if it is present. If it is not present it then Jetty's HttpClient is used if present. Closes gh-23491 --- .../client/DefaultWebClientBuilder.java | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClientBuilder.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClientBuilder.java index c8796e91f7..c3aef0520e 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClientBuilder.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClientBuilder.java @@ -25,9 +25,11 @@ import java.util.function.Consumer; import org.springframework.http.HttpHeaders; import org.springframework.http.client.reactive.ClientHttpConnector; +import org.springframework.http.client.reactive.JettyClientHttpConnector; import org.springframework.http.client.reactive.ReactorClientHttpConnector; import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; @@ -41,6 +43,17 @@ import org.springframework.web.util.UriBuilderFactory; * @since 5.0 */ final class DefaultWebClientBuilder implements WebClient.Builder { + private static final boolean jettyHttpClientPresent; + + private static final boolean reactorNettyHttpClientPresent; + + static { + ClassLoader classLoader = DefaultWebClientBuilder.class.getClassLoader(); + jettyHttpClientPresent = ClassUtils.isPresent( + "org.eclipse.jetty.client.HttpClient", classLoader); + reactorNettyHttpClientPresent = ClassUtils.isPresent( + "reactor.netty.http.client.HttpClient", classLoader); + } @Nullable private String baseUrl; @@ -234,10 +247,20 @@ final class DefaultWebClientBuilder implements WebClient.Builder { return ExchangeFunctions.create(this.connector, this.exchangeStrategies); } else { - return ExchangeFunctions.create(new ReactorClientHttpConnector(), this.exchangeStrategies); + return ExchangeFunctions.create(createDefaultClientHttpConnector(), this.exchangeStrategies); } } + private ClientHttpConnector createDefaultClientHttpConnector() { + if (reactorNettyHttpClientPresent) { + return new ReactorClientHttpConnector(); + } + else if (jettyHttpClientPresent) { + return new JettyClientHttpConnector(); + } + throw new IllegalStateException("No suitable default ClientHttpConnector found"); + } + private UriBuilderFactory initUriBuilderFactory() { if (this.uriBuilderFactory != null) { return this.uriBuilderFactory;