okhttp3-5.x について
okhttp3-5.xは、JavaとAndroid向けHTTPクライアントOkHttp 5.xの利用を支援するリファレンススキルです。リクエスト処理、接続、キャッシュ、インターセプター、TLS設定、監視、MockWebServerによるテストを扱います。
主な機能
- 01同期・非同期HTTP呼び出し
- 02HTTP/2とコネクションプール
- 03レスポンスキャッシュとインターセプター
- 04TLS設定と証明書ピンニング
- 05呼び出しの監視とMockWebServerでのテスト
活用シーン
- 01JavaまたはAndroidでのREST APIクライアント構築
- 02リクエストの再試行、認証、リダイレクトの設定
- 03レスポンスキャッシュや呼び出しログの追加
- 04MockWebServerを使ったHTTPクライアントのテスト
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ full-stack-skills/ java-skills --skill okhttp3-5.xインストール後、Claude Code で/okhttp3-5.xを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
examples/interceptors-examples.mdhttps-examples.mdbasic-usage.mdcaching-examples.mdreferences/events.mdconnections.mdhttps.mdconfiguration.mdcalls.mdsecurity.mdcaching.mdinterceptors.mdrecipes.md詳細
OkHttp 5.x リファレンス(v5.4.0)
OkHttp は、HTTP/2 サポート、コネクションプーリング、透過的な GZIP、レスポンスキャッシュを備えた、デフォルトで効率的な HTTP クライアントです。よくある接続の問題から自動的に復旧し、最初の接続に失敗した場合は別のアドレスを試みます。
公式ドキュメントのソース
権威ある情報はすべて、公式の OkHttp サイトにあります。
OkHttp が準拠する RFC 標準:
- HTTP セマンティクス — RFC 9110
- HTTP キャッシュ — RFC 9111
- HTTP/1.1 — RFC 9112
- HTTP/2 — RFC 9113
- WebSocket — RFC 6455
- SSE — サーバー送信イベント
- Happy Eyeballs — RFC 6555
機能の適用範囲
✅ 得意分野
- HTTP/2 サポート — 同じホストへのすべてのリクエストでソケットを共有します
- コネクションプーリング — レイテンシを低減し、接続を自動的に再利用します
- 透過的な GZIP — ダウンロードサイズを自動的に縮小します
- レスポンスキャッシュ — 繰り返しのリクエストでネットワークアクセスを回避します
- インターセプター — 呼び出しの監視、書き換え、再試行に対応します(アプリケーション層とネットワーク層)
- Fast Fallback(Happy Eyeballs RFC 6555)— IPv4/IPv6 の接続を並行して試みます
- TLS 1.3、ALPN、証明書ピンニング
- EventListener API — HTTP 呼び出しのメトリクスを取得します
- MockWebServer — HTTP/HTTPS/HTTP/2 クライアントをテストします
- GraalVM Native Image のサポート
- Java 9 Modules のサポート(5.2 以降)
- 依存関係管理用 BOM
⚠️ 要件
- Java 8 以降、または Android 5.0 以降(API レベル 21 以降)
- Kotlin Multiplatform:Maven プロジェクトでは
okhttpではなくokhttp-jvmアーティファクトを使用する必要があります - Okio と Kotlin stdlib が必要です(推移的依存関係)
- 証明書ピンニングには、サーバーの TLS 管理者との調整が必要です
❌ 対象外(代替手段あり)
- ボディ付き GET — OkHttp はボディ付き GET を許可しません(POST を使用してください)
- カスタムキャッシュの実装 — Cache はインターフェースではありません(カスタムのキャッシュロジックにはインターセプターを使用してください)
- 不正な HTTP リクエスト — OkHttp は RFC に厳密に従います
- 古い Android(5.0 未満)— API 9 以降には OkHttp 3.12.x ブランチを使用してください
- 古い Java(8 未満)— Java 7 以降には OkHttp 3.12.x ブランチを使用してください
OkHttp を使用すべきでないケース:
- ボディ付き GET リクエスト(代わりに POST を使用してください)
- カスタムキャッシュの実装(インターセプターを使用してください)
- 不正な HTTP リクエスト(OkHttp は RFC に厳密に従います)
- Android 5.0 未満(OkHttp 3.12.x を使用してください)
- Java 8 未満(OkHttp 3.12.x を使用してください)
このスキルを使用する場面
ユーザーが次のことを必要としている場合に、このスキルを使用してください。
- Java または Android で HTTP/HTTPS リクエストを送信する
- コネクションプーリングを備えた REST API クライアントを構築する
- レスポンスキャッシュを実装する
- リクエスト/レスポンスのインターセプター(ロギング、認証、圧縮)を追加する
- TLS バージョンと暗号スイートを設定する
- セキュリティのために証明書をピンニングする
- EventListener で HTTP 呼び出しのパフォーマンスを監視する
- MockWebServer で HTTP クライアントをテストする
- リダイレクト、再試行、認証チャレンジを処理する
- HTTP/2 の多重化を使用する
5.x の新機能(4.x との比較)
OkHttp 5.x の主な変更点:
- Kotlin Multiplatform — JVM と Android のアーティファクトを分離しました(Maven では
okhttp-jvm) - Happy Eyeballs(RFC 6555) — Fast Fallback がデフォルトで有効になり、IPv4 と IPv6 の接続を並行して試行します
- MockWebServer 3 — 新しい座標(
mockwebserver3)、JUnit 4 への依存なし、不変の API - GraalVM Native Image — 自動的にサポートされます。例については
okcurlモジュールを参照してください - Java 9 モジュール(JPMS) — 適切な
module-info.javaファイル(5.2 以降) - 仮想スレッド — Java 21 の仮想スレッドをサポートします(
synchronizedの代わりに Lock/Condition を使用) - インターセプターの強化(5.4) — インターセプターで
OkHttpClient.Builderの設定をオーバーライドできるようになりました - Call タグ(5.3) — アプリケーション固有のメタデータを Call に付加できます
- Zstd 圧縮(5.2) — Zstandard 圧縮用の
okhttp-zstdモジュール - QUERY HTTP メソッド(5.2) — QUERY メソッドをサポートします
- HTTP 101 レスポンス(5.2) — 接続アップグレード用の Response.socket
クイックスタート
Gradle:
dependencies {
implementation(platform("com.squareup.okhttp3:okhttp-bom:5.4.0"))
implementation("com.squareup.okhttp3:okhttp")
implementation("com.squareup.okhttp3:logging-interceptor")
}
Maven(JVM — okhttp-jvm を使用する必要があります):
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp-bom</artifactId>
<version>5.4.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp-jvm</artifactId>
</dependency>
</dependencies>
最小限の GET:
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url("https://api.example.com/users").build();
try (Response response = client.newCall(request).execute()) {
System.out.println(response.body().string());
}
最小限の JSON POST:
RequestBody body = RequestBody.create("{\"name\":\"Alice\"}", MediaType.get("application/json"));
Request request = new Request.Builder().url("https://api.example.com/users").post(body).build();
try (Response response = client.newCall(request).execute()) {
System.out.println(response.body().string());
}
ワークフロー
ステップ 1. 環境を確認する — Java 8 以降または Android 5 以降であることを確認し、Maven(okhttp-jvm)または Gradle(okhttp)を選択します
ステップ 2. OkHttpClient を設定する — タイムアウト、接続プール、キャッシュ、インターセプター、TLS を設定します
ステップ 3. Request を構築する — URL、メソッド、ヘッダー、ボディを設定します
ステップ 4. Call を実行する — 同期(execute())または非同期(enqueue())で実行します
ステップ 5. Response を処理する — ステータスを確認し、ボディを読み取り、エラーを処理します
重要:OkHttpClient の設定
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.callTimeout(60, TimeUnit.SECONDS) // Entire call timeout
.connectionPool(new ConnectionPool(5, 5, TimeUnit.MINUTES))
.cache(new Cache(new File("cache-dir"), 50L * 1024L * 1024L)) // 50 MiB
.addInterceptor(new LoggingInterceptor()) // Application interceptor
.addNetworkInterceptor(new NetworkInterceptor()) // Network interceptor
.followRedirects(true)
.followSslRedirects(true)
.retryOnConnectionFailure(true)
.build();
主な設定オプション:
| Builder メソッド | 影響 | デフォルト |
|---|---|---|
connectTimeout(int, TimeUnit) | TCP 接続タイムアウト | 10 秒 |
readTimeout(int, TimeUnit) | ソケット読み取りタイムアウト | 10 秒 |
writeTimeout(int, TimeUnit) | ソケット書き込みタイムアウト | 10 秒 |
callTimeout(int, TimeUnit) | Call 全体のタイムアウト(すべての手順) | 制限なし |
connectionPool(ConnectionPool) | 接続プールの設定 | アイドル状態 5 件、キープアライブ 5 分 |
cache(Cache) | レスポンスキャッシュ(デフォルトでは無効) | null |
followRedirects(boolean) | HTTP リダイレクトに従う | true |
followSslRedirects(boolean) | HTTPS↔HTTP リダイレクトに従う | true |
retryOnConnectionFailure(boolean) | 古い接続で再試行する | true |
dns(Dns) | カスタム DNS リゾルバー | システム DNS |
proxy(Proxy) | 単一のプロキシ | null(直接接続) |
proxySelector(ProxySelector) | リクエストごとのプロキシ選択 | システムのデフォルト |
authenticator(Authenticator) | HTTP 認証チャレンジ | なし |
certificatePinner(CertificatePinner) | 証明書のピン留め | なし |
sslSocketFactory(SSLSocketFactory, X509TrustManager) | カスタム TLS | プラットフォームのデフォルト |
connectionSpecs(List<ConnectionSpec>) | TLS バージョンと暗号スイート | MODERN_TLS |
eventListenerFactory(EventListener.Factory) | イベントの監視 | なし |
詳細については、references/configuration.md を参照してください。
重要:リクエストの送信
Request の構築:
Request request = new Request.Builder()
.url("https://api.example.com/users/1")
.header("Authorization", "Bearer token123")
.addHeader("Accept", "application/json")
.get()
.build();
JSON ボディを使用した POST:
RequestBody body = RequestBody.create(jsonString, MediaType.get("application/json"));
Request request = new Request.Builder()
.url("https://api.example.com/users")
.post(body)
.build();
フォームデータを使用した POST:
RequestBody formBody = new FormBody.Builder()
.add("username", "alice")
.add("password", "secret")
.build();
マルチパートアップロード:
RequestBody fileBody = RequestBody.create(new File("photo.jpg"), MediaType.get("image/jpeg"));
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("title", "My Photo")
.addFormDataPart("photo", "photo.jpg", fileBody)
.build();
PUT/DELETE、リクエストとレスポンスのライフサイクルについては、references/calls.md を参照してください。
重要:レスポンスの処理
同期:
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
String body = response.body().string();
int code = response.code();
String contentType = response.header("Content-Type");
}
非同期:
client.newCall(request).enqueue(new Callback() {
@Override public void onFailure(Call call, IOException e) { e.printStackTrace(); }
@Override public void onResponse(Call call, Response response) throws IOException {
try (ResponseBody body = response.body()) {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
System.out.println(body.string());
}
}
});
後続処理、再試行、Dispatcher については、references/calls.md を参照してください。
重要:インターセプター
アプリケーションインターセプター — キャッシュされたレスポンスの場合も、元のリクエストを確認できます:
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new LoggingInterceptor())
.build();
ネットワークインターセプター — 実際のネットワークリクエスト(OkHttp が追加したヘッダーを含む)を確認できます:
OkHttpClient client = new OkHttpClient.Builder()
.addNetworkInterceptor(new LoggingInterceptor())
.build();
ロギングインターセプター(組み込み):
import okhttp3.logging.HttpLoggingInterceptor;
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
アプリケーションインターセプターとネットワークインターセプターの違い、および GzipRequestInterceptor については、references/interceptors.md を参照してください。
重要:キャッシュ
キャッシュを有効にする:
OkHttpClient client = new OkHttpClient.Builder()
.cache(new Cache(new File("cache-dir"), 50L * 1024L * 1024L)) // 50 MiB
.build();
キャッシュイベント: CacheHit、CacheMiss、CacheConditionalHit
キャッシュを整理する:
cache.evictAll(); // Clear all
Iterator<String> urlIterator = cache.urls();
while (urlIterator.hasNext()) {
if (urlIterator.next().startsWith("https://api.example.com/")) urlIterator.remove();
}
削除やトラブルシューティングについては、references/caching.md を参照してください。
重要:接続
OkHttp は階層モデルを使用します:URL → Address → Route → Connection
- URL:リソース識別子(スキーム、ホスト、パス)
- Address:Web サーバーと静的設定(ポート、TLS 設定、プロトコル)
- Route:動的な情報(特定の IP、プロキシ、TLS バージョン)
- Connection:実際の TCP ソケット(プールされ、再利用されます)
Fast Fallback(Happy Eyeballs、5.0 以降):
- IPv6 と IPv4 を同時に試行します
- 最初に成功した接続を維持します
- 250ms の遅延後にほかの試行をキャンセルします
接続プーリングと Fast Fallback の詳細については、references/connections.md を参照してください。
重要:HTTPS/TLS
組み込みの ConnectionSpec は 4 種類です:
RESTRICTED_TLS— 最も厳格で、コンプライアンス対応向けですMODERN_TLS— デフォルトで、安全な最新のサーバー向けですCOMPATIBLE_TLS— 古いものの、引き続き安全なサーバー向けですCLEARTEXT— http:// URL 専用です
フォールバックの設定:
OkHttpClient client = new OkHttpClient.Builder()
.connectionSpecs(Arrays.asList(ConnectionSpec.MODERN_TLS, ConnectionSpec.COMPATIBLE_TLS))
.build();
証明書のピンニング:
OkHttpClient client = new OkHttpClient.Builder()
.certificatePinner(
new CertificatePinner.Builder()
.add("publicobject.com", "sha256/afwiKY3RxoMmLkuRW1l7QsPZTJPwDS2pdDROQjXw8ig=")
.build())
.build();
TLS のデバッグ、カスタム TrustManager、暗号スイートについては、references/https.md を参照してください。
重要:レシピ(よく使われるパターン)
| パターン | 説明 |
|---|---|
| 同期 GET | client.newCall(request).execute() |
| 非同期 GET | client.newCall(request).enqueue(callback) |
| 文字列/ファイルの POST | RequestBody.create(content, mediaType) |
| フォームの POST | FormBody.Builder().add(name, value) |
| マルチパートアップロード | MultipartBody.Builder().addFormDataPart(...) |
| 呼び出しごとの設定 | client.newBuilder().readTimeout(...).build() |
| 認証 | OkHttpClient.Builder().authenticator(...) |
| キャンセル | call.cancel() |
| アップロードの進捗状況 | RequestBody を ForwardingSink でラップします |
コード例の全体については、references/recipes.md を参照してください。
重要:セキュリティ
- TLS の設定 —
ConnectionSpec.MODERN_TLS(デフォルト)を使用します。古いサーバーではCOMPATIBLE_TLSにフォールバックします - 証明書のピンニング —
CertificatePinnerを使用して、信頼する CA を制限します - カスタム TrustManager — プラットフォームの CA を独自のものに置き換えます(サーバーの TLS 管理者による承認が必要です)
- Conscrypt — Conscrypt プロバイダー経由で BoringSSL を使用し、プラットフォーム間で一貫した TLS を実現します
TLS の歴史とプロバイダーの設定については、references/security.md を参照してください。
重要:イベント(EventListener)
イベントの順序(呼び出しが成功した場合):
callStart → dnsStart → dnsEnd → connectStart → secureConnectStart → secureConnectEnd → connectEnd → connectionAcquired → requestHeadersStart → requestHeadersEnd → responseHeadersStart → responseHeadersEnd → responseBodyStart → responseBodyEnd → connectionReleased → callEnd
プールされた接続(接続イベントをスキップします):
callStart → connectionAcquired → requestHeadersStart → requestHeadersEnd → responseHeadersStart → responseHeadersEnd → responseBodyStart → responseBodyEnd → connectionReleased → callEnd
並行呼び出しのファクトリー:
EventListener.Factory factory = new EventListener.Factory() {
@Override public EventListener create(Call call) {
return new TimingEventListener();
}
};
EventListener のコード全体、失敗/再試行イベント、10% のサンプリングについては、references/events.md を参照してください。
重要:MockWebServer
基本的な使い方:
MockWebServer server = new MockWebServer();
server.enqueue(new MockResponse().setBody("Hello World!"));
server.start();
Request request = new Request.Builder().url(server.url("/")).build();
try (Response response = client.newCall(request).execute()) {
assertEquals("Hello World!", response.body().string());
}
server.shutdown();
Maven(mockwebserver3 を使用):
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>mockwebserver3</artifactId>
<scope>test</scope>
</dependency>
RecordedRequest の検証については、references/calls.md を参照してください。
クイック修正
| エラー | 原因 | 修正方法 |
|---|---|---|
java.lang.NoClassDefFoundError: kotlin/jvm/internal/... | Kotlin stdlib が不足しています | OkHttp 5.x は KMP です。Maven では okhttp-jvm、Gradle では okhttp を指定してください |
SSLHandshakeException | TLS バージョンの不一致です | ConnectionSpec を確認してください。フォールバックとして COMPATIBLE_TLS を試してください |
SocketTimeoutException | サーバーの応答が遅すぎます | readTimeout または callTimeout を延長してください |
ConnectionPool の枯渇 | 同時リクエストが多すぎます | プールサイズを増やすか、Dispatcher の制限を設定した非同期呼び出しを使用してください |
IllegalStateException: cache is closed | キャッシュディレクトリが競合しています | ディレクトリごとに Cache インスタンスを 1 つだけ使用してください |
Certificate pinning failure | ピンが一致しません | 証明書のローテーション後にピンを更新してください |
IOException: Canceled | 呼び出しがキャンセルされました | キャンセルのロジックを確認してください。早まってキャンセルしないでください |
ProtocolException: HTTP/209 | HTTP メソッドが無効です | OkHttp は RFC に準拠しています。ボディ付きの GET ではなく POST を使用してください |
Maven の okhttp アーティファクトが空です | KMP アーティファクトの問題です | Maven プロジェクトでは okhttp-jvm を使用してください |
| GraalVM のネイティブイメージのビルドに失敗します | リフレクション設定が不足しています | GraalVM 設定の例については、okcurl モジュールを参照してください |
注意点
- Maven では
okhttp-jvmを使用する必要があります — OkHttp 5.x は Kotlin Multiplatform です。Maven ではokhttpアーティファクトは空です。JVM プロジェクトではokhttp-jvmを使用してください。 - GET にボディを含めることはできません — OkHttp は HTTP RFC に厳密に準拠しています。ボディ付きのリクエストには POST を使用してください。
- キャッシュはデフォルトで無効です — OkHttpClient.Builder で
Cacheを明示的に設定する必要があります。 - キャッシュディレクトリは専用にしてください — ディレクトリごとに Cache インスタンスは 1 つだけにしてください。ディレクトリを共有しないでください。
- レスポンスを最後まで読み取ってください — キャッシュするにはレスポンスを最後まで読み取る必要があります。一部しか読み取らない場合、キャッシュされません。
- Response のボディを閉じてください — 接続リークを防ぐため、常に Response を閉じてください(try-with-resources を使用します)。
- アプリケーションインターセプターとネットワークインターセプター — アプリケーションインターセプターは(キャッシュの場合も)1 回だけ実行されます。ネットワークインターセプターはネットワーク呼び出しごとに実行されます。
- Fast Fallback は 5.x でデフォルトです — IPv4 と IPv6 の試行を並行して行います。必要に応じて
fastFallback(false)で無効にしてください。 - ConnectionSpec はリリースごとに変更されます — TLS バージョンと暗号スイートは変更される場合があります。最新の状態を保ってください。
- 証明書ピンニングには調整が必要です — サーバーの TLS 管理者による承認が必要です。証明書のローテーション時にはピンを更新してください。
- Dispatcher の制限 — デフォルトでは、ホストごとに同時 5 件、合計 64 件です。
dispatcher(new Dispatcher(executorService))で設定してください。 - 透過的な GZIP 圧縮 — OkHttp は
Accept-Encoding: gzipを自動的に追加します。インターセプターには、ネットワークレベルで圧縮されたデータが表示されます。
参考資料
呼び出し
- calls.md — リクエスト/レスポンスのライフサイクル、書き換え、後続処理、再試行、Dispatcher
キャッシュ
- caching.md — キャッシュ設定、EventListener のキャッシュイベント、ディレクトリ管理、削除
接続
- connections.md — URL/Address/Route/Connection モデル、接続プール、Fast Fallback
イベント
- events.md — EventListener、Factory、同時呼び出し、失敗/再試行イベント
HTTPS
- https.md — ConnectionSpec、TLS のデバッグ、証明書ピンニング、カスタム TrustManager
インターセプター
- interceptors.md — アプリケーションとネットワークの違い、リクエスト/レスポンスの書き換え
レシピ
- recipes.md — 一般的なパターン:GET、POST、フォーム、マルチパート、認証、アップロードの進捗
セキュリティ
- security.md — TLS 設定の履歴、証明書プロバイダー、Conscrypt
設定
- configuration.md — OkHttpClient.Builder の完全なリファレンス、Maven/Gradle/BOM の依存関係