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

OKHttp拦截器解析

OKHttp涉及到拦截器大概的执行步骤为:

1.通过newCall生成RealCall对象

具体代码如下:

@Override public Call newCall(Request request) {return new RealCall(this, request, false /* for web socket */);}

2.调用Call的execute方法

当然这也可以是执行异步任务的enqueue方法,我们这里主要分析execute方法,在这个方法中调用getResponseWithInterceptorChain()从而调用拦截器。
具体代码如下:

/*** 同步执行网络请求并返回响应** @return 返回响应对象* @throws IOException 如果在执行请求过程中发生I/O错误*/@Override public Response execute() throws IOException {// 同步锁,确保同一时间只有一个线程执行该方法synchronized (this) {// 检查是否已经执行过,如果已经执行过则抛出异常if (executed) throw new IllegalStateException("Already Executed");// 标记为已执行executed = true;}// 捕获调用栈信息,用于调试和错误追踪captureCallStackTrace();try {// 将当前请求添加到调度器中,以便管理和执行client.dispatcher().executed(this);// 通过拦截器链获取响应Response result = getResponseWithInterceptorChain();// 如果响应为空,则抛出异常if (result == null) throw new IOException("Canceled");// 返回响应return result;} finally {// 请求完成后,从调度器中移除当前请求client.dispatcher().finished(this);}}

3.调用拦截器,处理相关拦截操作(责任链模式)

  /*** 通过拦截器链获取响应** @return 返回响应对象* @throws IOException 如果在获取响应过程中发生I/O错误*/Response getResponseWithInterceptorChain() throws IOException {// 构建一个完整的拦截器栈List<Interceptor> interceptors = new ArrayList<>();// 添加应用程序提供的拦截器interceptors.addAll(client.interceptors());// 添加重试和重定向拦截器interceptors.add(retryAndFollowUpInterceptor);// 添加桥接拦截器,用于处理请求和响应的头部信息interceptors.add(new BridgeInterceptor(client.cookieJar()));// 添加缓存拦截器,用于处理缓存interceptors.add(new CacheInterceptor(client.internalCache()));// 添加连接拦截器,用于建立网络连接interceptors.add(new ConnectInterceptor(client));// 如果不是WebSocket请求,添加网络拦截器if (!forWebSocket) {interceptors.addAll(client.networkInterceptors());}// 添加调用服务器拦截器,用于发送请求和接收响应interceptors.add(new CallServerInterceptor(forWebSocket));// 创建一个拦截器链Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0, originalRequest);// 执行拦截器链并返回响应return chain.proceed(originalRequest);}

4.拦截器执行,链式调用

核心类为:RealInterceptorChain
public final class RealInterceptorChain implements Interceptor.Chain {private final List<Interceptor> interceptors;private final StreamAllocation streamAllocation;private final HttpCodec httpCodec;private final RealConnection connection;private final int index;private final Request request;private int calls;public RealInterceptorChain(List<Interceptor> interceptors, StreamAllocation streamAllocation,HttpCodec httpCodec, RealConnection connection, int index, Request request) {this.interceptors = interceptors;this.connection = connection;this.streamAllocation = streamAllocation;this.httpCodec = httpCodec;this.index = index;this.request = request;}@Override public Connection connection() {return connection;}public StreamAllocation streamAllocation() {return streamAllocation;}public HttpCodec httpStream() {return httpCodec;}@Override public Request request() {return request;}// 这个是拦截器中执行的proceed方法@Override public Response proceed(Request request) throws IOException {return proceed(request, streamAllocation, httpCodec, connection);}public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec,RealConnection connection) throws IOException {...// Call the next interceptor in the chain.// 传入下一个拦截器的索引和拦截器List,生成RealInterceptorChain对象RealInterceptorChain next = new RealInterceptorChain(interceptors, streamAllocation, httpCodec, connection, index + 1, request);// 根据当前索引获取拦截器Interceptor interceptor = interceptors.get(index);// 我们的拦截器实现了intercept(chain)方法,通过intercept实现了调用拦截器链的操作Response response = interceptor.intercept(next);... return response;}
}

具体我们实现拦截器的简单例子如下:

public class CustomHeaderInterceptor implements Interceptor {@Overridepublic Response intercept(Chain next) throws IOException {Request originalRequest = next.request();// 添加自定义头部信息Request newRequest = originalRequest.newBuilder().header("Custom-Header", "Custom-Value").build();// 继续处理请求,我们可以看到,Response response = interceptor.intercept(next)传下来的next在这里执行了proceed方法。从而实现了链式调用return next.proceed(newRequest);}
}

相关文章:

OKHttp拦截器解析

OKHttp涉及到拦截器大概的执行步骤为&#xff1a; 1.通过newCall生成RealCall对象 具体代码如下&#xff1a; Override public Call newCall(Request request) {return new RealCall(this, request, false /* for web socket */);}2.调用Call的execute方法 当然这也可以是执…...

STM32标准库移植RT-Thread nano

STM32标准库移植RT-Thread Nano 哔哩哔哩教程链接&#xff1a;STM32F1标准库移植RT_Thread Nano 移植前的准备 stm32标准库的裸机代码&#xff08;最好带有点灯和串口&#xff09;RT-Thread Nano Pack自己的开发板 移植前的说明 本人是在读学生&#xff0c;正在学习阶段&a…...

c++11总结26——std::regex

std::regex 是 C11 引入的 正则表达式库&#xff0c;用于 字符串匹配、搜索和替换。 &#x1f539; 头文件&#xff1a;#include <regex> &#x1f539; 命名空间&#xff1a;std &#x1f539; 支持的匹配模式&#xff1a;ECMAScript&#xff08;默认&#xff09;、POS…...

langchain教程-12.Agent/工具定义/Agent调用工具/Agentic RAG

前言 该系列教程的代码: https://github.com/shar-pen/Langchain-MiniTutorial 我主要参考 langchain 官方教程, 有选择性的记录了一下学习内容 这是教程清单 1.初试langchain2.prompt3.OutputParser/输出解析4.model/vllm模型部署和langchain调用5.DocumentLoader/多种文档…...

leetcode_双指针 125.验证回文串

125.验证回文串 如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后&#xff0c;短语正着读和反着读都一样。则可以认为该短语是一个回文串 。 字母和数字都属于字母数字字符。 给你一个字符串 s&#xff0c;如果它是回文串 &#xff0c;返回 true &#xff…...

ML.NET库学习001:基于PCA的信用卡异常检查之样本处理与训练

文章目录 (文末提供数据集下载)ML.NET库学习001&#xff1a;基于PCA的信用卡异常检查之样本处理与训练目标项目概述代码结构概述1. **主要类和文件**2. **命名空间和使用指令**3. **数据类 (TransactionObservation)**4. **主程序入口 (Main 方法)**5. **数据预处理 (DataPrepr…...

【华为OD机考】华为OD笔试真题解析(1)--AI处理器组合

一、题目描述 某公司研发了一款高性能AI处理器&#xff0c;每台物理设备具备8颗AI处理器&#xff0c;编号分别为0、1、2、3、4、5、6、7。 编号0~3的处理器处于同一链路中&#xff0c;编号4~7的处理器处于另外一个链路中&#xff0c;不同链路中的处理器不能通信&#xff0c;如…...

edu小程序挖掘严重支付逻辑漏洞

edu小程序挖掘严重支付逻辑漏洞 一、敏感信息泄露 打开购电小程序 这里需要输入姓名和学号&#xff0c;直接搜索引擎搜索即可得到&#xff0c;这就不用多说了&#xff0c;但是这里的手机号可以任意输入&#xff0c;只要用户没有绑定手机号这里我们输入自己的手机号抓包直接进…...

力扣 279. 完全平方数

&#x1f517; https://leetcode.cn/problems/perfect-squares 题目 给你一个整数 n &#xff0c;返回 和为 n 的完全平方数的最少数量完全平方数可以拆解为两个相同数的乘积 思路 dp 公式&#xff0c;就是从看用哪个完全平方数 1 2 4 9…… 到当前 sum 的数量最少 代码 …...

鸿蒙生态潮起:开发者的逐浪之旅

鸿蒙生态潮起&#xff1a;开发者的逐浪之旅 在全球科技的澎湃浪潮中&#xff0c;鸿蒙生态宛如一座正在崛起的新大陆&#xff0c;熠熠生辉&#xff0c;吸引着无数开发者扬帆起航&#xff0c;探寻其中蕴藏的无限机遇&#xff0c;也直面诸多挑战。 鸿蒙生态的机遇&#xff0c;首先…...

Diskgenius系统迁移之后无法使用USB启动

前言 本文用于记录系统迁移中遇到的问题及解决方法&#xff0c;如有不对请指出&#xff0c;谢谢&#xff01; 现象 使用DiskGenius进行系统迁移后&#xff0c;使用USB启动失败&#xff0c;反复在品牌logo和黑屏之间切换&#xff0c;期间还会在左上角显示”reset system“报错…...

Kafka 可靠性探究—副本刨析

Kafka 的多副本机制提升了数据容灾能力。 副本通常分为数据副本与服务副本。数据副本是指在不同的节点上持久化同一份数据&#xff1b;服务副本指多个节点提供同样的服务&#xff0c;每个节点都有能力接收来自外部的请求并进行相应的处理。 1 副本刨析 1.1 相关概念 AR&…...

我的博文天地测试报告

我的博文天地测试报告 文章目录 我的博文天地测试报告 一.项目背景 二.项目功能 2.1 功能介绍 三.测试分类 3.1 功能测试 3.1.1 测试用例 3.1.2 实际执行测试的部分操作步骤/结果的截图 3.2 自动化测试 3.3 性能测试 3.1.2 用户登录 jmeter性能测试结果 性能测试遇到的困难 …...

EtherCAT主站IGH-- 35 -- IGH之pdo_list.h/c文件解析

EtherCAT主站IGH-- 35 -- IGH之pdo_list.h/c文件解析 0 预览一 该文件功能`pdo_list.c` 文件功能函数预览二 函数功能介绍`pdo_list.c` 中主要函数的作用1. `ec_pdo_list_init`2. `ec_pdo_list_clear`3. `ec_pdo_list_clear_pdos`4. `ec_pdo_list_total_size`5. `ec_pdo_list_a…...

嵌入式开发神器:Buildroot的介绍和使用方法

目录 引言**Buildroot 能做什么&#xff1f;****1. 生成交叉编译工具链&#xff08;Toolchain&#xff09;****2. 生成嵌入式 Linux 根文件系统&#xff08;RootFS&#xff09;****3. 编译 Linux 内核和设备树文件****4. 编译 Bootloader&#xff08;U-Boot&#xff09;****5. …...

JavaScript系列(61)--边缘计算应用开发详解

JavaScript边缘计算应用开发详解 &#x1f310; 今天&#xff0c;让我们深入探讨JavaScript的边缘计算应用开发。边缘计算是一种将计算和数据存储分布到更靠近数据源的位置的架构模式&#xff0c;它能够提供更低的延迟和更好的实时性能。 边缘计算基础架构 &#x1f31f; &am…...

【LeetCode】day15 142.环形链表II

142. 环形链表 II - 力扣&#xff08;LeetCode&#xff09; 题目描述 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则…...

代理对象与目标对象

1. 定义&#xff1a;代理对象和目标对象 1.1 目标对象&#xff08;Target Object&#xff09; 目标对象是指 被增强的原始对象&#xff0c;即需要通过 AOP 切面&#xff08;Aspect&#xff09;增强功能的业务对象&#xff08;原始类&#xff09;。增强逻辑&#xff08;Advice…...

【Kubernetes Pod间通信-第3篇】Kubernetes中Pod与ClusterIP服务之间的通信

引言 我们之前了解了在不同场景下,Kubernetes中Pod之间的通信是如何路由的。 【Kubernetes Pod间通信-第1篇】在单个子网中使用underlay网络实现Pod到Pod的通信【Kubernetes Pod间通信-第2篇】使用BGP实现Pod到Pod的通信现在,我们来看看在集群中,Pod与服务之间的通信是如何…...

DNN(深度神经网络)近似 Lyapunov 函数

import torch import torch.nn as nn import torch.optim as optim import matplotlib.pyplot as plt # from torchviz import make_dot import torchviz# 1. Lyapunov 函数近似器&#xff08;MLP 结构&#xff09; class LyapunovNet(nn.Module):def __init__(self, input_dim…...

无人水下航行器(UUV)与无人航空系统(UAS)时空会合关键技术研究附Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f34a;个人信条&#xff1a;格物致知,完整Matlab代码及仿真咨询…...

PyTorch模型调试神器:用TensorBoard+torchsummary快速定位网络结构问题

PyTorch模型调试神器&#xff1a;用TensorBoardtorchsummary快速定位网络结构问题 当你在PyTorch中构建复杂的神经网络时&#xff0c;是否经常遇到以下困扰&#xff1a;模型训练时突然报出维度不匹配的错误&#xff0c;却不知道具体是哪一层出了问题&#xff1f;或者模型参数数…...

腾讯混元OCR实战体验:上传图片秒出文字,支持100多种语言识别

腾讯混元OCR实战体验&#xff1a;上传图片秒出文字&#xff0c;支持100多种语言识别 1. 产品概述与核心优势 1.1 什么是腾讯混元OCR 腾讯混元OCR是基于腾讯混元原生多模态架构开发的轻量化文字识别系统。这个工具最吸引人的地方在于&#xff0c;它只需要1B&#xff08;10亿&…...

tao-8k Embedding模型部署教程:支持中文长文本的高兼容性向量服务

tao-8k Embedding模型部署教程&#xff1a;支持中文长文本的高兼容性向量服务 你是不是遇到过这样的问题&#xff1f;想把一段很长的中文文档&#xff0c;比如一篇技术报告、一份产品说明书&#xff0c;甚至是一本小说的章节&#xff0c;转换成计算机能理解的向量&#xff0c;…...

C++引用:高效编程的技巧

C引用的本质与特性 引用是已存在变量的别名&#xff0c;与变量共享同一内存地址。声明时必须初始化且不可更改绑定对象&#xff1a; int x 10; int& ref x; // ref成为x的别名 ref 20; // 修改x的值引用与指针的核心区别 初始化要求&#xff1a;引用必须声明时初始…...

macOS安装OpenClaw全流程:Qwen2.5-VL-7B图文模型调试技巧

macOS安装OpenClaw全流程&#xff1a;Qwen2.5-VL-7B图文模型调试技巧 1. 为什么选择OpenClawQwen2.5-VL组合 去年冬天第一次接触OpenClaw时&#xff0c;我正被重复性的截图标注工作折磨得焦头烂额。当时尝试过几个自动化工具&#xff0c;要么功能太局限&#xff0c;要么需要把…...

Qwen3.5-9B实战落地:政务公文校对+政策条款关联性分析案例

Qwen3.5-9B实战落地&#xff1a;政务公文校对政策条款关联性分析案例 1. 项目背景与模型介绍 Qwen3.5-9B是一款拥有90亿参数的开源大语言模型&#xff0c;在政务场景中展现出强大的应用潜力。这个模型特别适合处理结构化文本分析任务&#xff0c;能够理解复杂的政策语言和公文…...

Swashbuckle.AspNetCore 生产环境部署指南:安全配置API文档的终极方案

Swashbuckle.AspNetCore 生产环境部署指南&#xff1a;安全配置API文档的终极方案 【免费下载链接】Swashbuckle.AspNetCore Swagger tools for documenting APIs built on ASP.NET Core 项目地址: https://gitcode.com/gh_mirrors/sw/Swashbuckle.AspNetCore Swashbuck…...

Termius Pro功能免费解锁指南:修改background-process.js实现永久订阅

Termius订阅机制解析与安全使用建议 Termius作为一款广受开发者欢迎的SSH客户端工具&#xff0c;其Pro版本提供了诸多实用功能。本文将深入探讨Termius的订阅验证机制工作原理&#xff0c;并从技术角度分析如何安全合规地使用该工具。 1. Termius订阅机制技术解析 Termius采用典…...

Pixel Aurora Engine真实作品:支持物理位移反馈的UI交互+生成图联动演示

Pixel Aurora Engine真实作品&#xff1a;支持物理位移反馈的UI交互生成图联动演示 1. 像素极光创意引擎介绍 Pixel Aurora Engine&#xff08;像素极光引擎&#xff09;是一款融合AI生成技术与复古游戏美学的创意工具。这款"虚拟游戏机"采用8-bit像素风格界面&…...