您的位置:首页 > 理论基础 > 计算机网络

OkHttp的深入研究:Jesse Wilson(三)

2016-03-07 11:35 429 查看

OkHttp 2.0

June 23, 2014
OkHttp started as a fork of Android’s
HttpURLConnection
.
That gave us a solid foundation to build upon. Working behind a widely-used API meant that upgrading from AOSP’s
HttpURLConnection
to
ours was easy: just configure URLs stream handler factory.
But we’ve outgrown the
HttpURLConnection
API.
Its fully-synchronous API means that application code needs to manage how requests are dispatched. Requests and responses are together in one class which makes certain operations awkward or inefficient. Most painfully, we’re
limited in what we can expose: Was my request redirected? Did the response come from a cache? OkHttp knows the answers to these questions but the
HttpURLConnection
API
offers no way for you to ask them.

Request, Response, and Call

With 2.0, OkHttp introduces three fundamental types:
Request
,
Response
,
and
Call
. A call executes a request to produce a response.
You can do that synchronously with a blocking call:

private final OkHttpClient client = new OkHttpClient();

public void run() throws Exception {
Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.build();

Call call = client.newCall(request);
Response response = call.execute();

if (!response.isSuccessful()) {
throw new IOException("Unexpected code " + response);
}
System.out.println(response.body().string());
}


Or asynchronously with a callback:

Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.build();

Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override public void onFailure(Request request, IOException e) {
logger.log(Level.SEVERE, "Failed to execute " + request, e);
}

@Override public void onResponse(Response response) throws IOException {
if (!response.isSuccessful()) {
throw new IOException("Unexpected code " + response);
}
System.out.println(response.body().string());
}
});


A Request’s Journey

Above we complained that
HttpURLConnection
lacks
APIs to ask how a response was reached. With redirects and caching, that journey can be interesting! One handy example is what happens when OkHttp downloads its own jar file from Maven Central.

Following Redirects

First we’re redirected from the HTTP to the HTTPS site:

> GET http://repository.sonatype.org/.../redirect?a=okhttp&v=LATEST 
< 301 Moved Permanently
< Location: https://repository.sonatype.org/.../redirect?a=okhttp&v=LATEST


Next we’re redirected from the LATEST tag to the specific file we want.

> GET https://repository.sonatype.org/.../redirect?a=okhttp&v=LATEST 
< 307 Temporary Redirect
< Location: https://repository.sonatype.org/.../content/.../okhttp-2.0.0.jar


Finally we download the file. The response includes headers to make caching possible.

> GET https://repository.sonatype.org/.../content/.../okhttp-2.0.0.jar 
< 200 OK
< Last-Modified: Sat, 21 Jun 2014 01:00:00 GMT
< ETag: "{SHA1{4c8d1536dba3812cc1592090dc20c47a4ed3c35e}}"


OkHttp exposes these redirects with
Response.priorResponse()
.
If you’re redirected multiple times, you will have a chain of prior responses. These will be returned in order from last-to-first; reverse them for chronological order:

List<Response> chainedResponses = new ArrayList<>();
for (Response r = response; r != null; r = r.priorResponse()) {
chainedResponses.add(r);
}
Collections.reverse(chainedResponses);

for (Response r : chainedResponses) {
System.out.println(r.request().url());
}


Cache and Network Responses

If we re-download the same URL, OkHttp’s response cache may kick in.
Response
offers
two methods to check where a response came from:
cacheResponse()
and
networkResponse()
.
Note that for conditional gets, both will be present!
When downloading a jar file from Maven Central,
Response.cacheResponse()
returns
the cached response from above:

> GET https://repository.sonatype.org/.../content/.../okhttp-2.0.0.jar 
< 200 OK
< Last-Modified: Sat, 21 Jun 2014 01:00:00 GMT
< ETag: "{SHA1{4c8d1536dba3812cc1592090dc20c47a4ed3c35e}}"


This cached response required validation from the server. OkHttp needed to ask, “Has
the cached value changed?” Checking
Response.networkResponse()
confirms
that it had not:

> GET https://repository.sonatype.org/.../content/.../okhttp-2.0.0.jar > If-Modified-Since: Sat, 21 Jun 2014 01:00:00 GMT
> If-None-Match: "{SHA1{4c8d1536dba3812cc1592090dc20c47a4ed3c35e}}"

< 304 Not Modified


Prior responses from redirects also support
cacheResponse()
and
networkResponse()
.
Use this to interrogate whether any part of a response used the network.

Upgrading to OkHttp 2.0

OkHttp 2.0 is not backwards-compatible. The changelog describes what’s changed and what’s gone. For example, to continue using the
HttpURLConnection
API,
you will need the optional
okhttp-urlconnection
dependency.
To make upgrading easier, we’ve also released OkHttp 1.6 which is the 1.5 code plus some new 2.0 APIs. Use 1.6 to transition to 2.x APIs.
Get OkHttp from Maven or download it from the project website. Read more code examples in the project’s Recipes
doc.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: