拦截器基础概念:OkHttp 拦截器链、Interceptor 接口、intercept 方法签名

原理概述

OkHttp 的拦截器(Interceptor)是贯穿整个 HTTP 请求生命周期的核心扩展点。每个拦截器负责在请求发送前、响应返回后执行自定义逻辑,多个拦截器以链式结构串联,形成一个有序的拦截器链(Interceptor Chain)。

当 OkHttp 发起一个请求时,请求会依次经过注册的所有拦截器,每个拦截器可读取/修改请求、记录日志、重试、缓存、添加头信息等。处理后通过 chain.proceed() 将请求传递给下一个拦截器,最终到达网络层。响应则沿原路反向流回,每个拦截器在拿到响应后也可进行后处理。

核心接口与签名

接口/类说明关键方法签名
Interceptor 拦截器接口,所有自定义拦截器需实现该接口 Response intercept(Chain chain)
Chain 拦截器链,提供请求对象并传递到下一拦截器 Request request()
Response proceed(Request request)
Request 请求对象,包含 URL、方法、Header、Body Builder 模式构造,不可变
Response 响应对象,包含状态码、Header、Body Builder 模式构造,不可变

拦截器链执行流程

下图展示了两个自定义拦截器在链中的顺序执行与数据流转:

OkHttp 拦截器链执行流程 HttpClient 拦截器 A (日志/头处理) 拦截器 B (重试/缓存) 网络层 响应 链上每个拦截器通过 chain.proceed(request) 将请求交给下一环 响应按逆序返回,拦截器可分别处理请求阶段与响应阶段 请求方向 → 响应方向 ←

intercept 方法签名解析

public interface Interceptor {
    Response intercept(Chain chain) throws IOException;
}

唯一方法 intercept 接收 Chain 对象,返回 Response 对象。典型实现模式:

class LoggingInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        // 请求前处理
        long t1 = System.nanoTime();
        Response response = chain.proceed(request);
        // 响应后处理
        long t2 = System.nanoTime();
        System.out.println("请求耗时: " + (t2 - t1) / 1e6 + " ms");
        return response;
    }
}
关键设计点:
  • chain.proceed() 只能调用一次(除非实现重试/重定向逻辑),否则会抛出异常。
  • Request 对象不可变,需要修改时应通过 request.newBuilder() 创建新实例。
  • 拦截器可感知请求/响应完整结构,包括 Header、Body、连接属性。

拦截器类型对比

类型注册方式触发时机典型用途
应用拦截器addInterceptor()在重定向/重试之前,只执行一次日志、压缩、统一头处理
网络拦截器addNetworkInterceptor()在连接建立后,每次网络请求都会触发调试网络细节、修改连接参数
常见错误:忘记在自定义拦截器中调用 chain.proceed(request) 会导致请求挂死;重复调用 proceed 会抛出 IllegalStateException。务必在拦截器内部保持正确的链式调用。

小结