Apache HttpClient 4.5 Transport
Maven Dependencies
Add the Juneau transport module and Apache HttpClient 4.5 to your project:
<!-- Juneau transport adapter -->
<dependency>
<groupId>org.apache.juneau</groupId>
<artifactId>juneau-rest-client-apache-httpclient-45</artifactId>
<version>${juneau.version}</version>
</dependency>
<!-- Apache HttpClient 4.5 (transitive from the adapter, pinned here for clarity) -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.14</version>
</dependency>
The Juneau adapter module declares httpclient:4.5.14 as a dependency, so the second block can
be omitted if you are happy with the version the adapter brings in.
Overview
juneau-rest-client-apache-httpclient-45 provides an HttpTransport implementation backed by
Apache HttpClient 4.5.x (org.apache.httpcomponents:httpclient). Consider it when:
- Your project already pulls in Apache HttpClient 4.5 and you want a single shared client instance across the application.
- You need mature, battle-tested connection pooling, proxy support, cookie management, or NTLM / Kerberos authentication built into HC 4.5.
- You are migrating an existing HC 4.5 integration to the Juneau REST client API incrementally.
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.apachehttpclient45.*;
RestClient client = RestClient.builder()
.transport(ApacheHc45Transport.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();
ApacheHc45Transport.create() is shorthand for ApacheHc45Transport.builder().build(). It
creates a default CloseableHttpClient via HttpClients.createDefault().
Auto-discovery (no explicit transport call)
Simply add the module to the classpath and omit the .transport(...) call:
// The ApacheHc45TransportProvider registered via ServiceLoader takes over automatically.
RestClient client = RestClient.builder()
.serializer(Json5Serializer.DEFAULT)
.parser(Json5Parser.DEFAULT)
.rootUrl("https://api.example.com")
.build();
Configuring the Underlying HttpClient
Use ApacheHc45TransportBuilder.httpClient(CloseableHttpClient) to supply your own
pre-configured CloseableHttpClient. The transport takes ownership of the client and closes it
when RestClient.close() is called.
import org.apache.http.impl.client.*;
import org.apache.http.impl.conn.*;
import org.apache.juneau.marshall.json5.*;
import org.apache.juneau.rest.client.*;
import org.apache.juneau.rest.client.apachehttpclient45.*;
CloseableHttpClient apacheClient = HttpClients.custom()
.setConnectionManager(new PoolingHttpClientConnectionManager())
.setMaxConnPerRoute(20)
.setMaxConnTotal(100)
.build();
RestClient client = RestClient.builder()
.transport(ApacheHc45Transport.builder()
.httpClient(apacheClient)
.build())
.serializer(Json5Serializer.DEFAULT)
.parser(Json5Parser.DEFAULT)
.rootUrl("https://api.example.com")
.build();
Connection Pooling
Apache HttpClient 4.5 ships PoolingHttpClientConnectionManager, which reuses TCP connections
across requests. Tune it to match your workload:
import org.apache.http.impl.conn.*;
var cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(200); // total connections in the pool
cm.setDefaultMaxPerRoute(20); // max connections per host:port pair
CloseableHttpClient poolingClient = HttpClients.custom()
.setConnectionManager(cm)
.build();
SSL / TLS
Pass a custom SSLContext or SSLConnectionSocketFactory when building the
CloseableHttpClient:
import javax.net.ssl.*;
import org.apache.http.ssl.*;
import org.apache.http.impl.client.*;
SSLContext sslContext = SSLContexts.custom()
.loadTrustMaterial(trustStore, null)
.build();
CloseableHttpClient tlsClient = HttpClients.custom()
.setSSLContext(sslContext)
.build();
Request Timeouts
Configure connect and socket timeouts via RequestConfig:
import org.apache.http.client.config.*;
import org.apache.http.impl.client.*;
RequestConfig config = RequestConfig.custom()
.setConnectTimeout(5_000) // ms to establish a connection
.setSocketTimeout(30_000) // ms waiting for data
.setConnectionRequestTimeout(2_000) // ms to lease a connection from the pool
.build();
CloseableHttpClient timedClient = HttpClients.custom()
.setDefaultRequestConfig(config)
.build();
Lifecycle
The RestClient lifecycle maps directly to the underlying CloseableHttpClient:
// Build once at application startup
RestClient client = RestClient.builder()
.transport(ApacheHc45Transport.builder().httpClient(myClient).build())
.build();
// Use throughout the application lifetime; wrap each response in try-with-resources
try (var resp = client.get("/items").run()) {
return resp.body().as(ItemList.class);
}
// At application shutdown — closes the CloseableHttpClient
client.close();
See Also
- HTTP Transport Adapters — overview and adapter comparison
- Apache HttpClient 5.0 Transport — upgrade path to the 5.x API
- Next-Generation REST Client — full guide to the NG client