当前位置: 首页 > news >正文

okhttp3.Interceptor简介-笔记

1. Interceptor 简介

okhttp3.Interceptor 是 OkHttp 提供的一个核心接口,用于拦截 HTTP 请求和响应,允许开发者在请求发送前和响应接收后插入自定义逻辑。它在构建灵活、可扩展的网络请求逻辑中扮演着重要角色。常见的用途包括:

  • 添加请求头(如认证 Token、上下文信息)
  • 日志记录(调试请求和响应)
  • 请求重试或错误处理
  • 缓存控制
  • 性能监控(如记录请求耗时)

Interceptor 接口提供一个 intercept(Chain chain) 方法,该方法接收一个 Chain 对象,通过调用 chain.proceed(request) 可以继续请求链的处理。

其中Chain 提供了以下关键方法:

  • Request request():获取当前请求。
  • Response proceed(Request request):将请求传递给下一个拦截器或服务器。
  • Connection connection():获取当前连接信息(仅限网络拦截器)。

2. Interceptor代码示例

step1.定义拦截器

定义一个 AuthInterceptor,用于添加请求头(认证 Token):

import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;import java.io.IOException;public class AuthInterceptor implements Interceptor {private final String authToken;public AuthInterceptor(String authToken) {this.authToken = authToken;}@Overridepublic Response intercept(Chain chain) throws IOException {// 获取原始请求Request originalRequest = chain.request();// 构建新的请求,添加认证 Token 到请求头Request newRequest = originalRequest.newBuilder().header("Authorization", "userDefineAuthToken-" + authToken).build();// 继续请求链return chain.proceed(newRequest);}
}

再定义一个LoggingInterceptor,用于记录请求日志

import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;import java.io.IOException;public class LoggingInterceptor implements Interceptor {@Overridepublic Response intercept(Chain chain) throws IOException {Request request = chain.request();long startTime = System.currentTimeMillis();// 记录请求信息System.out.println("┌───────────────────────────────────────────────────────────────────────");System.out.println("│ Sending request: " + request.method() + " " + request.url());System.out.println("│ requestHeaders: ");for (String headerName : request.headers().names()) {System.out.println("│   " + headerName + ": " + request.header(headerName));}// 执行请求并记录响应Response response = chain.proceed(request);long duration = System.currentTimeMillis() - startTime;// 记录响应信息System.out.println("│ Received response: " + response.code() + " in " + duration + "ms");System.out.println("│ responseHeaders: ");for (String headerName : response.headers().names()) {System.out.println("│   " + headerName + ": " + response.header(headerName));}System.out.println("└───────────────────────────────────────────────────────────────────────");return response;}
}

step2.使用 OkHttpClient 添加拦截器并发送请求


import java.io.IOException;import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;public class InterceptorExample {public static void main(String[] args) {// 0. 创建认证 TokenString token = "your_access_token_here";// 1. 创建 Interceptor 实例AuthInterceptor authInterceptor = new AuthInterceptor(token);LoggingInterceptor loggingInterceptor = new LoggingInterceptor();// 2. 构建 OkHttpClient 并添加拦截器// 拦截器会按照添加顺序依次执行,因此 AuthInterceptor 会在 LoggingInterceptor 之前运行。OkHttpClient client = new OkHttpClient.Builder().addInterceptor(authInterceptor) // 添加token拦截器.addInterceptor(loggingInterceptor)  // 添加日志拦截器.build();// 3. 创建请求对象(例如:GET /data)Request request = new Request.Builder().url("https://www.baidu.com/s?wd=iphone")  // 替换为你的 API 地址.get().build();// 4. 发送请求并处理响应try (Response response = client.newCall(request).execute()) {if (!response.isSuccessful()) {throw new IOException("Unexpected code " + response);}// 读取并打印响应体(可选)String responseBody = response.body().string();System.out.println("Response Body:\n" + responseBody);} catch (IOException e) {e.printStackTrace();}}
}

输出示例如下: 

┌───────────────────────────────────────────────────────────────────────
│ Sending request: GET https://www.baidu.com/s?wd=iphone
│ requestHeaders: 
│   Authorization: userDefineAuthToken-your_access_token_here
│ Received response: 200 in 228ms
│ responseHeaders: 
│   Access-Control-Allow-Credentials: true
│   Date: Mon, 12 May 2025 12:12:59 GMT
│   Vary: Accept-Encoding
└───────────────────────────────────────────────────────────────────────
Response Body:
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="utf-8"><title>百度安全验证</title>......
</head>
<body><div class="timeout hide-callback"><div class="timeout-img"></div></div>......
</body>
</html>

step3.注意事项

  • Token 安全性:请勿在生产环境中硬编码 Token,应从安全存储或认证服务中动态获取。
  • 异常处理:示例中使用了基本的异常处理逻辑,建议根据业务需求进行扩展。
  • 资源管理:使用 try-with-resources 或手动调用 response.body().close() 确保资源被释放。
  • 日志安全性:避免在生产环境中记录敏感信息(如 Token、密码、请求体内容),可在正式环境移除或禁用日志拦截器。
  • 性能影响:日志记录可能增加请求处理时间,建议在调试阶段启用,生产环境关闭。
  • 扩展性:可以根据需求自定义日志格式,例如添加请求体、响应体内容(需谨慎处理)。

3. 扩展&总结

3.1 拦截器的分类与使用场景

拦截器类型特点
应用拦截器每个请求只执行一次,适用于添加统一的请求头、日志等通用逻辑。
网络拦截器在重试时会再次执行,适用于网络层的处理,如缓存、代理等。

添加方式区别:

  • 应用拦截器:client.addInterceptor(...)
  • 网络拦截器:client.addNetworkInterceptor(...)

两种拦截器其实都是 Interceptor 的实现类,只是在功能上做了区分:

3.2 注意事项

  1. 线程安全:拦截器可能在多个线程中运行,需注意线程安全。
  2. 性能影响:避免在拦截器中执行耗时操作(如数据库查询)。
  3. 避免无限循环:确保 proceed 方法被调用,否则请求会阻塞。
  4. 请求不可变性:修改请求时需通过 newBuilder() 创建副本,不能直接修改原始请求。
  5. 敏感信息:日志拦截器中应避免打印敏感数据(如 Token、密码)。

3.3 总结

okhttp3.Interceptor 是一个强大且灵活的工具,能够帮助开发者在 HTTP 请求生命周期中插入各种逻辑。通过合理使用拦截器,可以简化网络请求的复杂度,提高代码的可维护性和复用性。在实际开发中,建议结合具体业务需求选择合适的拦截器类型,并遵循最佳实践。

相关文章:

  • Babel进阶:如何自定义插件?
  • 配置Hadoop集群-免密登录
  • VM中 ubuntu 网卡不显示
  • 大核极坐标码
  • 滑动窗口/单调队列
  • 告别数据僵尸!Redis实现自动清理过期键值对
  • Linux环境基础开发工具的使用(yum、vim、gcc、g++、gdb、make/Makefile)
  • Git 用法总结
  • [Git]ssh模式每次提交都要输入密码
  • 【AutoGen革命】多智能体协作系统的架构设计与工程实践
  • Java后端文件类型检测(防伪造)
  • C++.Windows图形
  • DVWA靶场保姆级通关教程--07SQL注入下
  • Open CASCADE学习|由大量Edge构建闭合Wire:有序与无序处理的完整解析
  • Java SE所需工具与常见类型和运算符介绍
  • SWMM在城市排水防涝规划中的实战应用:模型校准、情景模拟与工程决策
  • TCPIP详解 卷1协议 七 防火墙和网络地址转换
  • vue3+three 搭建平面上滚动旋转的几何体
  • 第一章 应急响应-webshell查杀
  • 无线定位之 二 SX1302 网关源码 thread_down 线程详解
  • 睡觉总做梦是睡眠质量差?梦到这些事,才要小心
  • 俄乌拟在土耳其举行会谈,特朗普:我可能飞过去
  • 外企聊营商|波音速度:创新审批促“起飞”
  • 技术派|更强的带刀侍卫:从054B型战舰谈谈世界护卫舰发展
  • 中国科考船在钓鱼岛附近活动,外交部:完全是中国主权权利范围内的事
  • 全国层面首次!《防震减灾基本知识与技能大纲》发布