java-httpclient-webclient-spring-boot-starter: Powering Spring’s WebClient with Java 11’s HttpClient

java-httpclient-webclient-spring-boot-starter is a library that I created to provide a quick and easy way to use Java 11’s HttpClient as Spring’s WebClient‘s client HTTP connector. If you’re using Spring Boot 2.3 or later, it’s worth checking out. The library is in Maven Central so it’s easy to incorporate into any new or existing proejct regardless of your choice to use Gradle, Maven, or another dependency management / build system. Check out the java-httpclient-webclient-spring-boot-starter project’s README.md for more information.

What Is the Java 11 HttpClient

Java 11 includes a new HttpClient providing a better, easier, universal way to perform HTTP client operations from Java applications deprecating HttpUrlConnection. The Java 11 HttpClient is the product of years of work to produce a high quality, maintainable API and implementation that can serve the Java ecosystem for years to come. The effort kicked off in 2014 and after much effort was finally included in Java 11 (and all subsequent releases) in 2018. It offers many advantages over its predecessor, HttpUrlConnection, and in many cases, removes the need to use HTTP client libraries such as Reactor Netty and the Jetty HTTP client entirely.

Spring Will Eventually Use Java 11’s HttpClient

Spring WebClient predates the Java 11 HttpClient but offers much of the same design and functionality. Both are non-blocking, reactive, and feature similar overall designs. However, Spring WebClient isn’t actually a client itself – it’s an abstraction over other clients. By default, Spring WebClient will use Reactor Netty’s HTTP Client, and if it’s not present, tries to use Jetty HTTP client. It would make sense to prefer Java 11’s HttpClient when running on Java 11, but unfortunately, that’s not possible until Spring is built using Java 11 which is planned to be done for Spring Framework 6 in 2021. There is a Pull Request for JDK 11 HttpClient integration with WebClient so one can be confident that Spring WebClient will change to prefer Java 11 HttpClient when it’s possible to do so.

Why Use Java 11’s HttpClient?

One of the most compelling reasons to use Java 11’s HttpClient over other WebClient implementations such as Reactor Netty and the Jetty HTTP Client is that it is built in to Java. It’s generally preferable to reduce dependencies when possible, so eliminating the dependency on a big, complex library such as Reactor Netty is a win.

Another reason is that Java 11’s HttpClient respects all Java configuration providing a consistent, unsurprising solution. It is in clear contrast to alternatives; for example, Reactor Netty doesn’t respect Java’s proxy settings: one has to override Netty configuration in addition to Java’s built in configure to consistently use a proxy.

Java 11’s HttpClient includes support for TLS 1.3, HTTP/2, asynchronous or asynchronous use, and support for reactive-streams. These features provide a modern offering prepared for today’s world as well as the future. And because it’s a part of Java, it will continue to be maintained, get new features, and receive security fixes for years to come.

There are some nice libraries to help with unit and integration testing when using Java 11’s HttpClient including HttpClientMock. I find these libraries to be easier to use than those that exist for Reactor Netty or mocking WebClient itself. mockwebserver remains an option for testing, too, and such tests need not be modified when trying different WebClient implementations.

Using java-httpclient-webclient-spring-boot-starter

To use this starter, you need:

  • Java 11 (or later)
  • Spring Boot 2.3.0 (or later)
  • Spring WebClient, which is included in Spring WebFlux

Add the Dependency

Add a dependency on this starter your dependency manager of choice, making sure to use the latest version:

For Gradle:

dependencies {
	runtimeOnly 'com.integralblue:java-httpclient-webclient-spring-boot-starter:VERSION'
}

For Maven:

<dependency>
	<groupId>com.integralblue</groupId>
	<artifactId>java-httpclient-webclient-spring-boot-starter</artifactId>
	<version>VERSION</version>
    <scope>runtime</scope>
</dependency>

Use the Autowired WebClient.Builder

Follow the advice given in the Spring Boot documentation under Calling REST Services with WebClient when using WebClient by autowiring an instance of WebClient.Builder and using that to create the WebClient instance.

For example:

@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);
    }

WebClient.create() and WebClient.builder().build() will not apply the customizations from this starter meaning WebClients created using those approaches will not use Java 11’s HttpClient.

Contributions and Feedback Welcome

I intend to support this library until versions of Spring and Spring Boot are released that include support for the Java 11 HttpClient in Spring’s WebClient. Pull requests, issues, and other forms of contribution and feedback are always welcome.

CC BY-SA 4.0 java-httpclient-webclient-spring-boot-starter: Powering Spring’s WebClient with Java 11’s HttpClient by Craig Andrews is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.