Android 中 OkHttp 的自定义 Interceptor 实现统一请求头添加

在 Android 中使用 OkHttp 的自定义 Interceptor 实现统一请求头添加是一种高效的方式,可以避免在每个请求中重复设置头部。以下是详细实现步骤:

1. 创建自定义拦截器类

java 复制代码
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;

public class HeaderInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        // 1. 获取原始请求
        Request originalRequest = chain.request();
        
        // 2. 添加统一请求头(可扩展更多)
        Request newRequest = originalRequest.newBuilder()
                .header("User-Agent", "MyApp/Android/1.0.0")
                .header("Accept-Language", "zh-CN")
                .header("Authorization", getAuthToken()) // 示例:动态token
                .header("Custom-Header", "Value")
                // 添加更多统一头部...
                .build();
        
        // 3. 继续执行请求
        return chain.proceed(newRequest);
    }

    // 示例方法:获取动态认证token(根据实际情况实现)
    private String getAuthToken() {
        // 这里可以是获取本地存储的token
        return "Bearer your_token_here";
    }
}

2. 在 OkHttpClient 中注册拦截器

java 复制代码
// 创建 OkHttpClient 实例
OkHttpClient client = new OkHttpClient.Builder()
        .addInterceptor(new HeaderInterceptor()) // 添加统一头部拦截器
        // 可选:添加其他拦截器(如日志拦截器)
        .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
        .build();

3. 使用 OkHttpClient 发送请求(示例)

java 复制代码
// 创建请求(无需单独设置统一头部)
Request request = new Request.Builder()
        .url("https://api.example.com/data")
        .build();

// 异步执行
client.newCall(request).enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        // 处理失败
    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        // 处理响应
    }
});

关键点说明

  1. 拦截器类型选择:

    • addInterceptor:应用拦截器,处理非重定向请求
    • addNetworkInterceptor:网络拦截器,处理实际网络请求(包含重定向)
  2. 动态头部处理:

    java 复制代码
    // 示例:根据请求URL动态添加头部
    if (originalRequest.url().toString().contains("/api/secure")) {
        newRequestBuilder.header("Security-Key", "special_key");
    }
  3. 覆盖优先级:

    • 拦截器添加的头部 会覆盖 请求中设置的相同名称头部

    • 若需保留请求特定头部,使用以下方式:

      java 复制代码
      if (!originalRequest.headers().contains("Special-Header")) {
          newRequestBuilder.header("Special-Header", "default");
      }

高级场景处理

1. 需要动态 token 的场景
java 复制代码
.header("Authorization", getCurrentToken()) // 实现动态获取

// 实现示例
private String getCurrentToken() {
    return App.getAuthManager().getAccessToken();
}
2. 条件性添加头部
java 复制代码
Request.Builder builder = originalRequest.newBuilder();
if (isUserLoggedIn()) {
    builder.header("User-ID", getUserId());
}
3. 多模块差异化处理
java 复制代码
String path = originalRequest.url().encodedPath();
if (path.startsWith("/api/v1")) {
    builder.header("API-Version", "v1");
} else if (path.startsWith("/api/v2")) {
    builder.header("API-Version", "v2");
}

完整流程图

是 否 发起请求 拦截器处理 是否添加统一头部? 添加预设头部 保留原始头部 执行网络请求 返回响应

通过这种方式,您可以:

  1. 集中管理所有公共请求头
  2. 动态处理认证信息
  3. 根据不同请求条件添加不同头部
  4. 减少代码重复和维护成本

提示:对于敏感信息(如认证 token),建议结合 Android 的安全存储机制(如 EncryptedSharedPreferences)进行存储和获取。

相关推荐
Yyyyyy~6 分钟前
【Java】多线程初阶
java
蜗牛互联网6 分钟前
Java 17 调用视觉 Responses API:JSON 约束与人工复核路由
java·人工智能·后端
应用市场31 分钟前
不用一张图片的像素小游戏:小人是字符串,房间是矩形,平衡靠两千个假玩家
android·kotlin·游戏开发
SL_staff1 小时前
物模型三要素误用避坑指南:属性、事件、服务的正确建模逻辑
java
一条泥憨鱼1 小时前
【Redis | 黑马点评】短信登录功能 源码深度分析
java·redis·后端·session·黑马点评
威哥爱编程1 小时前
【AI全栈12-12】Spring Boot 3.x → 4.x 迁移实操:Jakarta 11、Jackson 3 与 AI 2.0
java·spring boot·后端
威哥爱编程1 小时前
【AI全栈12-11】Spring Boot 把 AI 接口真正上线扛量:限流 / 降级 / 可观测
java·spring boot·后端
小蒜学长1 小时前
基于SpringBoot+uni-app的闪洁家政系统的设计与实现(代码+数据库+LW)
java·spring boot·后端·uni-app·家政服务
stevenzqzq1 小时前
android 对渠道的理解
android
QEasycloud2 小时前
BOM接口抛转失败钉钉通知策略实战教程:MySQL异常日志到钉钉消息的端到端配置
android·mysql·钉钉