OkHttp 的拦截器有哪些
OkHttp 的拦截器主要分为两大类:内置拦截器和自定义拦截器。以下是详细的分类和说明:
一、内置拦截器(OkHttp 自动添加)
这些拦截器由 OkHttp 内部自动管理,按照固定顺序执行:
-
RetryAndFollowUpInterceptor
- 处理请求失败后的重试和 HTTP 重定向(如 301/302 状态码)
- 自动处理认证挑战(如 401 认证失败)
-
BridgeInterceptor
- 补全缺失的请求头(如
Content-Type
、Host
、User-Agent
) - 自动处理 Gzip 压缩(添加
Accept-Encoding
头,解压响应体)
- 补全缺失的请求头(如
-
CacheInterceptor
- 根据缓存策略管理本地缓存
- 处理条件请求(如
If-Modified-Since
头)
-
ConnectInterceptor
- 建立与服务器的 TCP/TLS 连接
- 管理连接池(复用已有连接)
-
CallServerInterceptor
- 最终向服务器发送请求并读取响应
- 处理请求体和响应体的读写
二、自定义拦截器(开发者手动添加)
通过 OkHttpClient.Builder
添加,分为两种类型:
1. 应用拦截器(Application Interceptors)
- 添加方式:
.addInterceptor()
- 特点:
- 最先执行,最后获得响应
- 能拦截所有请求(包括缓存响应)
- 无法访问
Connection
对象(如 TLS 信息)
- 典型用途:
- 统一添加请求头(如 Token)
- 全局日志记录
- 请求/响应数据加解密
val client = OkHttpClient.Builder().addInterceptor(LoggingInterceptor()) // 应用拦截器.build()
2. 网络拦截器(Network Interceptors)
- 添加方式:
.addNetworkInterceptor()
- 特点:
- 仅在建立网络连接时触发(不拦截缓存响应)
- 可以访问
Connection
对象(如服务器 IP、TLS 协议) - 会跟随重定向和重试
- 典型用途:
- 网络层监控(如统计请求耗时)
- 修改重试策略
- 调试网络细节
val client = OkHttpClient.Builder().addNetworkInterceptor(StethoInterceptor()) // 网络拦截器.build()
三、常用自定义拦截器示例
1. 日志拦截器
class LoggingInterceptor : Interceptor {override fun intercept(chain: Interceptor.Chain): Response {val request = chain.request()// 记录请求信息val response = chain.proceed(request)// 记录响应信息return response}
}
2. 认证拦截器
class AuthInterceptor(private val token: String) : Interceptor {override fun intercept(chain: Interceptor.Chain): Response {val newRequest = chain.request().newBuilder().header("Authorization", "Bearer $token").build()return chain.proceed(newRequest)}
}
3. 缓存控制拦截器
class CacheControlInterceptor : Interceptor {override fun intercept(chain: Interceptor.Chain): Response {val request = chain.request()val modifiedRequest = request.newBuilder().header("Cache-Control", "public, max-age=60").build()return chain.proceed(modifiedRequest)}
}
4. 请求重试拦截器
class RetryInterceptor(private val maxRetries: Int) : Interceptor {override fun intercept(chain: Interceptor.Chain): Response {var lastException: IOException? = nullfor (i in 1..maxRetries) {try {return chain.proceed(chain.request())} catch (e: IOException) {lastException = eThread.sleep(i * 1000L) // 指数退避}}throw lastException!!}
}
四、拦截器执行顺序图示
应用拦截器(开发者添加)
↓
RetryAndFollowUpInterceptor(内置)
↓
BridgeInterceptor(内置)
↓
CacheInterceptor(内置)
↓
ConnectInterceptor(内置)
↓
网络拦截器(开发者添加)
↓
CallServerInterceptor(内置)
五、如何选择拦截器类型?
场景 | 推荐类型 |
---|---|
统一添加请求头 | 应用拦截器 |
全局日志记录 | 应用拦截器 |
监控实际网络请求 | 网络拦截器 |
调试 TLS/连接信息 | 网络拦截器 |
修改重定向行为 | 重写 RetryAndFollowUpInterceptor |
六、注意事项
- 性能影响:拦截器中的耗时操作会阻塞网络请求
- 修改请求体:需谨慎处理,避免破坏数据一致性
- 错误处理:拦截器中的异常会直接中断请求链
- 线程安全:拦截器可能被多个线程同时调用
OkHttp 的拦截器机制是其强大灵活性的核心,合理使用可以高效实现统一认证、日志、缓存等全局功能。