Skip to main content

Apache HttpClient 5.x Transport

Maven Dependencies​

<!-- Juneau transport adapter -->
<dependency>
<groupId>org.apache.juneau</groupId>
<artifactId>juneau-rest-client-apache-httpclient-50</artifactId>
<version>${juneau.version}</version>
</dependency>

<!-- Apache HttpClient 5 (transitive from the adapter, pinned here for clarity) -->
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.6.1</version>
</dependency>

Overview​

juneau-rest-client-apache-httpclient-50 provides an HttpTransport implementation backed by Apache HttpClient 5.x (org.apache.httpcomponents.client5:httpclient5). Consider it when:

  • You are starting a new project and want the latest Apache HttpComponents API.
  • You need HTTP/2 support within the Apache HC ecosystem.
  • You are migrating an existing HC 5 integration to the Juneau REST client API.

The transport uses the classic (synchronous) CloseableHttpClient execution path from HC 5. Async-only HC 5 features (e.g., CloseableHttpAsyncClient) are not exposed; route calls through the transport interface as usual.

The transport is auto-discovered via ServiceLoader when the module is on the classpath. An explicit .transport(...) call always wins over auto-discovery.


Getting Started​

Zero-configuration default​

import org.apache.juneau.marshall.json5.*;
import org.apache.juneau.rest.client.*;
import org.apache.juneau.rest.client.apachehttpclient50.*;

RestClient client = RestClient.builder()
.transport(ApacheHc5Transport.create()) // wraps HttpClients.createDefault()
.serializer(Json5Serializer.DEFAULT)
.parser(Json5Parser.DEFAULT)
.rootUrl("https://api.example.com")
.build();

try (var resp = client.get("/users/123").run()) {
var user = resp.body().as(User.class);
}

client.close();

ApacheHc5Transport.create() is shorthand for ApacheHc5Transport.builder().build(). It creates a default CloseableHttpClient via org.apache.hc.client5.http.impl.classic.HttpClients.createDefault().

Auto-discovery​

Add the module to the classpath and omit the .transport(...) call:

RestClient client = RestClient.builder()
.serializer(Json5Serializer.DEFAULT)
.parser(Json5Parser.DEFAULT)
.rootUrl("https://api.example.com")
.build();

Configuring the Underlying HttpClient​

Use ApacheHc5TransportBuilder.httpClient(CloseableHttpClient) to supply your own CloseableHttpClient. The transport takes ownership of the client and closes it when RestClient.close() is called.

import org.apache.hc.client5.http.impl.classic.*;
import org.apache.juneau.marshall.json5.*;
import org.apache.juneau.rest.client.*;
import org.apache.juneau.rest.client.apachehttpclient50.*;

CloseableHttpClient apacheClient = HttpClients.createDefault();

RestClient client = RestClient.builder()
.transport(ApacheHc5Transport.builder()
.httpClient(apacheClient)
.build())
.serializer(Json5Serializer.DEFAULT)
.parser(Json5Parser.DEFAULT)
.rootUrl("https://api.example.com")
.build();

Connection Pooling​

Apache HttpClient 5 ships PoolingHttpClientConnectionManagerBuilder for pooled connection management:

import org.apache.hc.client5.http.impl.classic.*;
import org.apache.hc.client5.http.impl.io.*;

var cm = PoolingHttpClientConnectionManagerBuilder.create()
.setMaxConnTotal(200)
.setMaxConnPerRoute(20)
.build();

CloseableHttpClient poolingClient = HttpClients.custom()
.setConnectionManager(cm)
.build();

SSL / TLS​

import javax.net.ssl.*;
import org.apache.hc.client5.http.ssl.*;
import org.apache.hc.client5.http.impl.classic.*;
import org.apache.hc.client5.http.impl.io.*;

SSLContext sslContext = SSLContexts.custom()
.loadTrustMaterial(trustStore, null)
.build();

var cm = PoolingHttpClientConnectionManagerBuilder.create()
.setSSLSocketFactory(SSLConnectionSocketFactoryBuilder.create()
.setSslContext(sslContext)
.build())
.build();

CloseableHttpClient tlsClient = HttpClients.custom()
.setConnectionManager(cm)
.build();

Request Timeouts​

In HC 5, timeouts are set via RequestConfig:

import org.apache.hc.client5.http.config.*;
import org.apache.hc.core5.util.*;
import org.apache.hc.client5.http.impl.classic.*;

RequestConfig config = RequestConfig.custom()
.setConnectTimeout(Timeout.ofSeconds(5))
.setResponseTimeout(Timeout.ofSeconds(30))
.setConnectionRequestTimeout(Timeout.ofSeconds(2))
.build();

CloseableHttpClient timedClient = HttpClients.custom()
.setDefaultRequestConfig(config)
.build();

Differences from the HC 4.5 Adapter​

ConcernHC 4.5 (apachehttpclient45)HC 5 (apachehttpclient50)
GroupIdorg.apache.httpcomponentsorg.apache.httpcomponents.client5
ArtifactIdhttpclienthttpclient5
Transport classApacheHc45TransportApacheHc5Transport
Builder classApacheHc45TransportBuilderApacheHc5TransportBuilder
Timeout APIRequestConfig.setSocketTimeout(int ms)RequestConfig.setResponseTimeout(Timeout)
Connection managerPoolingHttpClientConnectionManagerPoolingHttpClientConnectionManagerBuilder

Lifecycle​

RestClient client = RestClient.builder()
.transport(ApacheHc5Transport.builder().httpClient(myClient).build())
.build();

try (var resp = client.get("/items").run()) {
return resp.body().as(ItemList.class);
}

client.close();

See Also​