Skip to main content

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​