OkHttp Transport
Maven Dependencies
<!-- Juneau transport adapter -->
<dependency>
<groupId>org.apache.juneau</groupId>
<artifactId>juneau-rest-client-okhttp</artifactId>
<version>${juneau.version}</version>
</dependency>
<!-- OkHttp 5 (transitive from the adapter, pinned here for clarity) -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp-jvm</artifactId>
<version>5.3.2</version>
</dependency>
The adapter targets OkHttp 5.x, whose Maven artifact is okhttp-jvm (not the older okhttp
artifact used by OkHttp 4.x). Make sure your dependency manager resolves the correct artifact.
Overview
juneau-rest-client-okhttp provides an HttpTransport implementation backed by
OkHttp 5.x (com.squareup.okhttp3:okhttp-jvm). Consider it when:
- You want transparent HTTP/2 with automatic HTTP/1.1 fallback.
- You are developing for Android, where OkHttp is the de-facto HTTP client.
- You want efficient request/response body streaming with minimal in-memory buffering (OkHttp streams the request body directly to the socket when the content length is known).
- You rely on OkHttp-native interceptors, authenticators, or cookie jars elsewhere in your
application and want to share the same
OkHttpClientinstance.
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.okhttp.*;
RestClient client = RestClient.builder()
.transport(OkHttpTransport.create()) // wraps new OkHttpClient()
.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();
OkHttpTransport.create() is shorthand for OkHttpTransport.builder().build(). It creates a
new OkHttpClient with default settings.
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 OkHttpClient
Use OkHttpTransportBuilder.httpClient(OkHttpClient) to supply your own OkHttpClient. The
transport will call dispatcher().executorService().shutdown() and
connectionPool().evictAll() on it when RestClient.close() is called.
import okhttp3.*;
import org.apache.juneau.marshall.json5.*;
import org.apache.juneau.rest.client.*;
import org.apache.juneau.rest.client.okhttp.*;
OkHttpClient okClient = new OkHttpClient.Builder()
.connectTimeout(java.time.Duration.ofSeconds(5))
.readTimeout(java.time.Duration.ofSeconds(30))
.build();
RestClient client = RestClient.builder()
.transport(OkHttpTransport.builder()
.httpClient(okClient)
.build())
.serializer(Json5Serializer.DEFAULT)
.parser(Json5Parser.DEFAULT)
.rootUrl("https://api.example.com")
.build();
Sharing One OkHttpClient Across Multiple RestClients
OkHttp's documentation strongly recommends sharing a single OkHttpClient instance across the
application so that its connection pool and thread pool are reused. Pass the same instance to
each adapter:
OkHttpClient shared = new OkHttpClient();
RestClient users = RestClient.builder()
.transport(OkHttpTransport.builder().httpClient(shared).build())
.rootUrl("https://users.example.com")
.build();
RestClient orders = RestClient.builder()
.transport(OkHttpTransport.builder().httpClient(shared).build())
.rootUrl("https://orders.example.com")
.build();
When sharing, managing the OkHttpClient lifecycle (shutdown) is the caller's responsibility.
Connection Pooling
OkHttp manages its connection pool internally. You can tune it via ConnectionPool:
import okhttp3.*;
OkHttpClient pooled = new OkHttpClient.Builder()
.connectionPool(new ConnectionPool(
20, // max idle connections
5, java.util.concurrent.TimeUnit.MINUTES)) // keep-alive duration
.build();
SSL / TLS
import javax.net.ssl.*;
import okhttp3.*;
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagers, trustManagers, null);
OkHttpClient tlsClient = new OkHttpClient.Builder()
.sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustManagers[0])
.build();
OkHttp Interceptors
OkHttp-native interceptors can be wired through the OkHttpClient builder and are transparent to
Juneau's own interceptor chain:
OkHttpClient intercepted = new OkHttpClient.Builder()
.addInterceptor(chain -> {
Request request = chain.request().newBuilder()
.addHeader("X-Correlation-Id", UUID.randomUUID().toString())
.build();
return chain.proceed(request);
})
.build();
Lifecycle and Shutdown
OkHttpTransport.close() drains the connection pool and shuts down the dispatcher's thread pool:
// httpClient.dispatcher().executorService().shutdown();
// httpClient.connectionPool().evictAll();
If you supplied a shared OkHttpClient, call close() on the last RestClient to use it, or
manage the OkHttpClient lifecycle yourself.
See Also
- HTTP Transport Adapters — overview and adapter comparison
- Next-Generation REST Client — full guide to the NG client