调用
HTTP client 的任务就是接受你传递的请求(request),然后产生响应(response)。原理很简单,在实践中却比较复杂。
Requests
每一个请求都包含一个URL,一个方法(比如GET
或者POST
),和请求头列表。请求还有可能包含一个body:指定内容类型的数据流。
Responses
响应(response)回应请求, 并带有状态码(比如200表示成功,404表示没找到资源), 响应头以及可选的响应体(body).
Rewriting Requests
当你提供一个HTTP request给OkHttp的时候,你是站在上层描述一个请求的: 使用这些请求头去请求这个URL。为了正确性和高效,OkHttp在传送请求之前会重写你提供的请求信息。
OkHttp会添加缺少的请求头,包括 Content-Length
, Transfer-Encoding
, User-Agent
, Host
, Connection
, 以及 Content-Type
。对于透明的响应也会添加Accept-Encoding
请求头,除非这个请求头已经提供了。如果你有cookie,OkHttp会把cookie添加到Cookie
请求头里。
有一些请求将会得到一个缓存后的响应。当这个缓存后的响应过期之后,OkHttp会执行一个 conditional GET 的请求,如果响应比之前的缓存更新,就会下载并更新缓存。这要求有类似If-Modified-Since
和If-None-Match
的请求头。
Rewriting Responses
如果使用了公开的压缩,OkHttp将会丢弃相应的响应头 Content-Encoding
和 Content-Length
,因为这些响应头不适用解压缩后的响应体。
如果 conditional GET 请求成功了,网络响应的内容将会按照规范直接合并到缓存中。
Follow-up Request
当你请求的URL发生了移动,web服务器将会返回一个状态码为302
的响应,指定文档的新URL地址,OkHttp将会请求跳转后的地址获取最终的响应。
如果响应要求认证,OkHttp将会询问Authenticator完成认证。如果认证器提供了证书,请求会带上证书重试。
Retrying Requests
有时连接会失败:不管是连接池出现问题断开了连接,还是web服务器本身不可达。如果有不同路由是可用的,OkHttp都会重新请求。
Calls
通过 rewrites, redirect, follo-ups 以及 retries,简单的请求可能有多次请求和响应。OkHttp使用Call表示一个完整的请求任务,即便中间可能需要多次请求和响应。
Call以下面其中一种方式执行:
- 同步: 线程阻塞到响应可读
- 异步: 请求在其他线程排队等待,当响应可读时回调函数会在其他线程执行
Call可以在任意线程取消。当Call还未完成时就取消,将会导致Call失败,正在往请求体里写数据的代码,或者从响应体里读数据的代码将会跑出 IOException异常。
Dispatch
对于同步请求调用,你需要负责管理可以有多少并发请求. 太多的并发连接会浪费资源,太少的并发连接会损害延迟。
对于一部请求调用,Dispatcher实现了最大并发请求策略。你可以设置最大数量 per-webserver(默认是5),或者 overall(默认是64)。