android okhttp怎么添加请求头

android okhttp怎么添加请求头,第1张

123456789101112131415161718192021222324final Request.Builder builder = new Request.Builder().url(url)builder.addHeader(key,value)  //将请求头以键值对形式添加,可添加多个请求头:

final Request request = builder.build()final OkHttpClient client = new OkHttpClient.Builder()        .readTimeout(30, TimeUnit.SECONDS)        .connectTimeout(10, TimeUnit.SECONDS)        .writeTimeout(60, TimeUnit.SECONDS)        .build() //设置各种超时时间final Call call = client.newCall(request)new Thread(new Runnable() {    @Override    public void run() {        try {            Response response = call.execute()             if (response != null) {                             } else {                            }        } catch (IOException e) {            e.printStackTrace()        }    }}).start()

HTTPS在传输数据之前需要客户端(浏览器)与服务端(网站)之间进行一次握手,在握手过程中将确立双方加密传输数据的密码信息。握手过程的简单描述如下:

浏览器将自己支持的一套加密算法、HASH算法发送给网站。

1.网站从中选出一组加密算法与HASH算法,并将自己的身份信息以证书的形式发回给浏览器。证书里面包含了网站地址,加密公钥,以及证书的颁发机构等信息。

2.浏览器获得网站证书之后,开始验证证书的合法性,如果证书信任,则生成一串随机数字作为通讯过程中对称加密的秘钥。然后取出证书中的公钥,将这串数字以及HASH的结果进行加密,然后发给网站。

3.网站接收浏览器发来的数据之后,通过私钥进行解密,然后HASH校验,如果一致,则使用浏览器发来的数字串使加密一段握手消息发给浏览器。

4.浏览器解密,并HASH校验,没有问题,则握手结束。接下来的传输过程将由之前浏览器生成的随机密码并利用对称加密算法进行加密。

创建一个新的 MFC 类,使其从 CCmdTarget 继承。对于这个示例,我们将该类称为 NegotiateCallback。

2.

使用 MFC 的 BEGIN_INTERFACE_PART 宏创建一个内部类,使其实现 IHttpNegotiate 接口。MFC 会将 IHttpNegotiate 查询委托给这个内部类。这些应该在该类的 .h 文件中。

BEGIN_INTERFACE_PART(HttpNegotiateObj, IHttpNegotiate)

STDMETHOD_(HRESULT, BeginningTransaction)(LPCWSTR szUrl,

LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders)

STDMETHOD_(HRESULT, OnResponse)(DWORD dwResponseCode,

LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders, LPWSTR*

pszAdditionalRequestHeaders)

END_INTERFACE_PART(HttpNegotiate

在OkHttp3中,其灵活性很大程度上体现在可以 intercept 其任意一个环节,而这个优势便是okhttp3整个请求响应架构体系的精髓所在,先放出一张主框架请求流程图,接着再分析源码。

这大概是一个最简单的一个例子了,在 new OkHttpClient() 内部使用构造器模式初始化了一些配置信息:支持协议、任务分发器(其内部包含一个线程池,执行异步请求)、连接池(其内部包含一个线程池,维护connection)、连接/读/写超时时长等信息。

第一行创建了一个 Dispatcher 任务调度器,它定义了三个双向任务队列,两个异步队列:准备执行的请求队列 readyAsyncCalls 、正在运行的请求队列 runningAsyncCalls ;一个正在运行的同步请求队列 runningSyncCalls ;

另外还有一个线程池 executorService ,这个线程池跟Android中的CachedThreadPool非常类似,这种类型的线程池,适用于大量的耗时较短的异步任务。 下一篇文章 将对OkHttp框架中的线程池做一个总结。

接下来接着看Request的构造,这个例子Request比较简单,指定了请求方式 GET 和请求 url

紧接着通过 OkHttpClient 和 Request 构造一个 Call 对象,它的实现是 RealCall

可以看到在 RealCall 的构造方法中创建了一个 RetryAndFollowUpInterceptor ,用于处理请求错误和重定向等,这是 Okhttp 框架的精髓 interceptor chain 中的一环,默认情况下也是第一个拦截器,除非调用 OkHttpClient.Builder#addInterceptor(Interceptor) 来添加全局的拦截器。关于拦截器链的顺序参见 RealCall#getResponseWithInterceptorChain() 方法。

可以看到,一个 Call 只能执行一次,否则会抛异常,这里创建了一个 AsyncCall 并将Callback传入,接着再交给任务分发器 Dispatcher 来进一步处理。

从 Dispatcher#enqueue() 方法的策略可以看出,对于请求的入队做了一些限制,若正在执行的请求数量小于最大值(默认64),并且此请求所属主机的正在执行任务小于最大值(默认5),就加入正在运行的队列并通过线程池来执行该任务,否则加入准备执行队列中。

现在回头看看 AsyncCall ,它继承自 NamedRunnable ,而 NamedRunnable 实现了 Runnable 接口,它的作用有2个:

①采用模板方法的设计模式,让子类将具体的 *** 作放在 execute() 方法中

②给线程指定一个名字,比如传入模块名称,方便监控线程的活动状态;

先看注释②的行finally块中执行的 client.dispatcher().finished(this)

其中 promoteCalls() 为推动下一个任务执行,其实它做的也很简单,就是在条件满足的情况下,将 readyAsyncCalls 中的任务移动到 runningAsyncCalls 中,并交给线程池来执行,以下是它的实现。

接下来就回到注释①处的响应内容的获取 getResponseWithInterceptorChain()

可以看这块重点就是 interceptors 这个集合,首先将前面的 client.interceptors() 全部加入其中,还有在创建 RealCall 时的 retryAndFollowUpInterceptor 加入其中,接着还创建并添加了 BridgeInterceptor、CacheInterceptor、ConnectInterceptor、CallServerInterceptor ,最后通过 RealInterceptorChain#proceed(Request) 来执行整个 interceptor chain ,可见把这个拦截器链搞清楚,整体流程也就明朗了。

从这段实现可以看出,是按照添加到 interceptors 集合的顺序,逐个往下调用拦截器的intercept()方法,所以在前面的拦截器会先被调用。这个例子中自然就是 RetryAndFollowUpInterceptor 了。

这个拦截器就如同它的名字 retry and followUp ,主要负责错误处理和重定向等问题,比如路由错误、IO异常等。

接下来就到了 BridgeInterceptor#intercept() ,在这个拦截器中,添加了必要请求头信息,gzip处理等。

这个拦截器处理请求信息、cookie、gzip等,接着往下是 CacheInterceptor

这个拦截器主要工作是做做缓存处理,如果有有缓存并且缓存可用,那就使用缓存,否则进行调用下一个拦截器 ConnectionInterceptor 进行网络请求,并将响应内容缓存。

这个拦截器主要是打开一个到目标服务器的 connection 并调用下一个拦截器 CallServerInterceptor ,这是拦截器链最后一个拦截器,它向服务器发起真正的网络请求。

从上面的请求流程图可以看出,OkHttp的拦截器链可谓是其整个框架的精髓,用户可传入的 interceptor 分为两类:

①一类是全局的 interceptor,该类 interceptor 在整个拦截器链中最早被调用,通过 OkHttpClient.Builder#addInterceptor(Interceptor) 传入;

②另外一类是非网页请求的 interceptor ,这类拦截器只会在非网页请求中被调用,并且是在组装完请求之后,真正发起网络请求前被调用,所有的 interceptor 被保存在 List<Interceptor>interceptors 集合中,按照添加顺序来逐个调用,具体可参考 RealCall#getResponseWithInterceptorChain() 方法。通过 OkHttpClient.Builder#addNetworkInterceptor(Interceptor) 传入;

相关阅读


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/bake/11857903.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-19
下一篇 2023-05-19

发表评论

登录后才能评论

评论列表(0条)

保存