调用¶
HTTP 客户端的工作是接受你的请求并生成其响应。这在理论上很简单,但在实践中会变得复杂。
请求¶
每个 HTTP 请求包含一个 URL、一个方法(例如 GET
或 POST
)和一系列头部。请求还可能包含一个请求体:一个特定内容类型的数据流。
响应¶
响应通过一个状态码(例如 200 表示成功,404 表示未找到)、头部和其可选的响应体来应答请求。
重写请求¶
当你向 OkHttp 提供 HTTP 请求时,你是在高层次描述请求:“使用这些头部获取这个 URL。” 为了正确性和效率,OkHttp 在传输请求之前会重写你的请求。
OkHttp 可能会添加原始请求中没有的头部,包括 Content-Length
、Transfer-Encoding
、User-Agent
、Host
、Connection
和 Content-Type
。除非头部已经存在,否则它会添加 Accept-Encoding
头部用于透明响应压缩。如果你有 cookie,OkHttp 会用它们添加一个 Cookie
头部。
一些请求会有缓存的响应。当这个缓存响应不是最新的时,如果更新的响应比缓存的要新,OkHttp 可以执行条件 GET 来下载更新的响应。这需要添加诸如 If-Modified-Since
和 If-None-Match
的头部。
重写响应¶
如果使用了透明压缩,OkHttp 将丢弃相应的响应头部 Content-Encoding
和 Content-Length
,因为它们不适用于解压后的响应体。
如果条件 GET 成功,将按照规范的指示合并来自网络和缓存的响应。
后续请求¶
当你请求的 URL 已移动时,Web 服务器将返回一个状态码,例如 302
,以指示文档的新 URL。OkHttp 将遵循重定向来检索最终响应。
如果响应发出授权质询,OkHttp 将要求 Authenticator
(如果已配置)来满足质询。如果认证器提供了凭据,则请求将重试并包含该凭据。
重试请求¶
有时连接会失败:要么池中的连接已过期并断开连接,要么 Web 服务器本身无法访问。如果存在不同的路由,OkHttp 将使用该路由重试请求。
调用¶
通过重写、重定向、后续请求和重试,你的简单请求可能会产生许多请求和响应。OkHttp 使用 Call
来建模通过必要数量的中间请求和响应来满足你的请求的任务。通常这不会很多!但令人欣慰的是,如果你的 URL 被重定向或者你故障转移到备用 IP 地址,你的代码仍将继续工作。
调用以以下两种方式之一执行:
- 同步: 你的线程会阻塞,直到响应可读。
- 异步: 你可以在任何线程上将请求入队,并在响应可读时在另一个线程上获得回调。
可以从任何线程取消调用。如果调用尚未完成,这将导致调用失败!正在写入请求体或读取响应体的代码在调用被取消时将遭遇 IOException
。
分发¶
对于同步调用,你需要自带线程并负责管理同时发起的请求数量。过多的同时连接会浪费资源;过少则会影响延迟。
对于异步调用,Dispatcher
实现了最大并发请求的策略。你可以设置每个 Web 服务器的最大数量(默认为 5)以及总体的最大数量(默认为 64)。