mcpField
O
okhttp3-5.x

okhttp3-5.x

github.com/full-stack-skills开发753 次安装4 周前更新
代码仓库

关于 okhttp3-5.x

okhttp3-5.x 是使用 OkHttp 5.x 的参考技能;OkHttp 是面向 Java 和 Android 的 HTTP 客户端。内容涵盖请求处理、连接、缓存、拦截器、TLS 配置、监控及使用 MockWebServer 测试。

主要功能

  1. 01同步与异步 HTTP 调用
  2. 02HTTP/2 与连接池
  3. 03响应缓存与拦截器
  4. 04TLS 配置与证书固定
  5. 05调用监控与 MockWebServer 测试

适用场景

  1. 01构建 Java 或 Android REST API 客户端
  2. 02配置请求重试、认证和重定向
  3. 03添加响应缓存或调用日志
  4. 04使用 MockWebServer 测试 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.md
https-examples.md
basic-usage.md
caching-examples.md
references/
events.md
connections.md
https.md
configuration.md
calls.md
security.md
caching.md
interceptors.md
recipes.md

详细介绍

OkHttp 5.x 参考(v5.4.0)

OkHttp 默认是一款高效的 HTTP 客户端,支持 HTTP/2、连接池、透明 GZIP 和响应缓存。它会自动恢复常见的连接问题,并在首次连接失败时尝试其他地址。

官方文档来源

所有权威信息均可在 OkHttp 官方网站查阅:

主题URL
概览https://square.github.io/okhttp/
调用https://square.github.io/okhttp/features/calls/
缓存https://square.github.io/okhttp/features/caching/
连接https://square.github.io/okhttp/features/connections/
事件https://square.github.io/okhttp/features/events/
HTTPShttps://square.github.io/okhttp/features/https/
拦截器https://square.github.io/okhttp/features/interceptors/
示例https://square.github.io/okhttp/recipes/
安全性https://square.github.io/okhttp/security/
API Javadochttps://square.github.io/okhttp/5.x/okhttp/okhttp3/
MockWebServerhttps://square.github.io/okhttp/mockwebserver/
5.x 变更日志https://square.github.io/okhttp/changelogs/changelog/
Maven Centralhttps://central.sonatype.com/artifact/com.squareup.okhttp3/okhttp
GitHubhttps://github.com/square/okhttp

OkHttp 遵循的 RFC 标准:

  • HTTP 语义 — RFC 9110
  • HTTP 缓存 — RFC 9111
  • HTTP/1.1 — RFC 9112
  • HTTP/2 — RFC 9113
  • WebSockets — RFC 6455
  • SSE — 服务器发送事件
  • Happy Eyeballs — RFC 6555

能力边界

✅ 擅长领域
  1. 支持 HTTP/2 — 发往同一主机的所有请求共用一个套接字
  2. 连接池 — 降低延迟并自动复用连接
  3. 透明 GZIP — 自动缩小下载内容的体积
  4. 响应缓存 — 避免重复请求时访问网络
  5. 拦截器 — 监控、重写和重试调用(应用层 + 网络层)
  6. 快速回退(Happy Eyeballs RFC 6555)— 并发尝试 IPv4/IPv6 连接
  7. TLS 1.3、ALPN、证书固定
  8. EventListener API — 捕获 HTTP 调用的指标
  9. MockWebServer — 测试 HTTP/HTTPS/HTTP/2 客户端
  10. 支持 GraalVM Native Image
  11. 支持 Java 9 模块(5.2+)
  12. 用于依赖管理的 BOM
⚠️ 要求
  1. Java 8+ 或 Android 5.0+(API 级别 21+)
  2. Kotlin Multiplatform:Maven 项目必须使用 okhttp-jvm 构件(而非 okhttp)
  3. 依赖 Okio 和 Kotlin 标准库(传递依赖)
  4. 使用证书固定时:需要与服务器 TLS 管理员协调
❌ 不适用范围(及替代方案)
  1. 带请求体的 GET — OkHttp 不允许 GET 请求携带请求体(请使用 POST)
  2. 自定义缓存实现 — Cache 不是接口(自定义缓存逻辑请使用拦截器)
  3. 高度无效的 HTTP 请求 — OkHttp 严格遵循 RFC
  4. 旧版 Android(低于 5.0)— API 9+ 请使用 OkHttp 3.12.x 分支
  5. 旧版 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) — 默认启用快速回退;并发尝试 IPv4/IPv6
  • MockWebServer 3 — 新坐标(mockwebserver3),不依赖 JUnit 4,API 不可变
  • GraalVM Native Image — 自动支持;示例请参阅 okcurl 模块
  • Java 9 模块(JPMS) — 提供规范的 module-info.java 文件(5.2+)
  • 虚拟线程 — 支持 Java 21 虚拟线程(使用 Lock/Condition,而非 synchronized)
  • 拦截器增强功能(5.4) — 拦截器现在可以覆盖 OkHttpClient.Builder 设置
  • 调用标签(5.3) — 为 Call 附加特定于应用的元数据
  • Zstd 压缩(5.2) — 提供 okhttp-zstd 模块以支持 Zstandard 压缩
  • 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)Socket 读取超时10 秒
writeTimeout(int, TimeUnit)Socket 写入超时10 秒
callTimeout(int, TimeUnit)整个调用的超时(所有步骤)不限
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 = 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 套接字(会被放入连接池并重复使用)

快速回退(Happy Eyeballs,5.0+):

  • 同时尝试 IPv6 和 IPv4
  • 保留第一个成功的连接
  • 延迟 250ms 后取消其他尝试

有关连接池和快速回退的详情,请参阅 references/connections.md。

关键:HTTPS/TLS

4 种内置 ConnectionSpec:

  • 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。

关键:常用模式

模式描述
同步 GETclient.newCall(request).execute()
异步 GETclient.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()
上传进度使用 ForwardingSink 封装 RequestBody

完整代码示例请参阅 references/recipes.md。

关键:安全

  • TLS 配置 — 使用 ConnectionSpec.MODERN_TLS(默认);较旧的服务器可回退到 COMPATIBLE_TLS
  • 证书固定 — 使用 CertificatePinner 限制受信任的 CA
  • 自定义 TrustManager — 用自定义 CA 替换平台 CA(需要服务器 TLS 管理员批准)
  • Conscrypt — 通过 Conscrypt provider 使用 BoringSSL,以确保跨平台 TLS 一致

有关 TLS 历史和 provider 配置,请参阅 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 stdlibOkHttp 5.x 是 KMP;确保在 Maven 中使用 okhttp-jvm,或在 Gradle 中使用 okhttp
SSLHandshakeExceptionTLS 版本不匹配检查 ConnectionSpec;尝试使用 COMPATIBLE_TLS 作为回退
SocketTimeoutException服务端响应太慢增大 readTimeout 或 callTimeout
ConnectionPool 耗尽并发请求过多增大连接池容量,或使用带有 Dispatcher 限制的异步调用
IllegalStateException: cache is closed缓存目录冲突确保每个目录只使用一个 Cache 实例
Certificate pinning failure证书固定值不匹配证书轮换后更新固定值
IOException: Canceled调用已取消检查取消逻辑;不要过早取消
ProtocolException: HTTP/209HTTP 方法无效OkHttp 严格遵循 RFC;带请求体时改用 POST,而不是 GET
Maven okhttp 构件为空KMP 构件问题Maven 项目请使用 okhttp-jvm
GraalVM 原生镜像构建失败缺少反射配置参见 okcurl 模块中的 GraalVM 配置示例

注意事项

  1. Maven 必须使用 okhttp-jvm — OkHttp 5.x 是 Kotlin Multiplatform;在 Maven 中,okhttp 构件为空。JVM 项目请使用 okhttp-jvm。
  2. GET 不能带请求体 — OkHttp 严格遵循 HTTP RFC。带请求体的请求请使用 POST。
  3. 缓存默认关闭 — 必须在 OkHttpClient.Builder 中显式配置 Cache。
  4. 缓存目录为独占目录 — 每个目录只能对应一个 Cache 实例。不要共享目录。
  5. 完整读取响应 — 缓存响应需要完整读取;部分读取不会被缓存。
  6. 关闭 Response 请求体 — 始终关闭 Response(使用 try-with-resources),以避免连接泄漏。
  7. 应用拦截器与网络拦截器 — 应用拦截器只运行一次(即使使用缓存也是如此);网络拦截器会针对每次网络调用运行。
  8. 5.x 默认启用 Fast Fallback — 并发尝试 IPv4/IPv6。必要时可通过 fastFallback(false) 禁用。
  9. ConnectionSpec 会随版本变化 — TLS 版本和密码套件可能会发生变化。请保持更新。
  10. 证书固定需要协调 — 需要服务器 TLS 管理员批准。证书轮换时必须更新固定值。
  11. Dispatcher 限制 — 默认值:每个主机并发 5 个,总计 64 个。通过 dispatcher(new Dispatcher(executorService)) 配置。
  12. 透明 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 依赖

评论

支持 Markdown