OKHttp

来源:互联网 发布:粉丝应援 知乎 编辑:程序博客网 时间:2024/06/05 17:06

同步GET

以下示例演示了如何同步发送GET请求,输出响应头以及将响应体转换为字符串。

private final OkHttpClient client = new OkHttpClient();

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

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

if (!response.isSuccessful()) throw new IOException(“Unexpected code ” + response);

Headers responseHeaders = response.headers();
for (int i = 0; i < responseHeaders.size(); i++) {
System.out.println(responseHeaders.name(i) + “: ” + responseHeaders.value(i));
}

System.out.println(response.body().string());
}

下面对以上代码进行简单说明:

client执行newCall方法会得到一个Call对象,表示一个新的网络请求。Call对象的execute方法是同步方法,会阻塞当前线程,其返回Response对象。通过Response对象的isSuccessful()方法可以判断请求是否成功。通过Response的headers()方法可以得到响应头Headers对象,可以通过for循环索引遍历所有的响应头的名称和值。可以通过Headers.name(index)方法获取响应头的名称,通过Headers.value(index)方法获取响应头的值。除了索引遍历,通过Headers.get(headerName)方法也可以获取某个响应头的值,比如通过headers.get(“Content-Type”)获得服务器返回给客户端的数据类型。但是服务器返回给客户端的响应头中有可能有多个重复名称的响应头,比如在某个请求中,服务器要向客户端设置多个Cookie,那么会写入多个Set-Cookie响应头,且这些Set-Cookie响应头的值是不同的,访问百度首页,可以看到有7个Set-Cookie的响应头,如下图所示:这里写图片描述为了解决同时获取多个name相同的响应头的值,Headers中提供了一个public List<String> values(String name)方法,该方法会返回一个List<String>对象,所以此处通过Headers对象的values(‘Set-Cookie’)可以获取全部的Cookie信息,如果调用Headers对象的get(‘Set-Cookie’)方法,那么只会获取最后一条Cookie信息。通过Response对象的body()方法可以得到响应体ResponseBody对象,调用其string()方法可以很方便地将响应体中的数据转换为字符串,该方法会将所有的数据放入到内存之中,所以如果数据超过1M,最好不要调用string()方法以避免占用过多内存,这种情况下可以考虑将数据当做Stream流处理。

异步GET

以下示例演示了如何异步发送GET网络请求,代码如下所示:

private final OkHttpClient client = new OkHttpClient();

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

client.newCall(request).enqueue(new Callback() {  @Override  public void onFailure(Call call, IOException e) {    e.printStackTrace();  }  @Override  public void onResponse(Call call, Response response) throws IOException {    if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);    Headers responseHeaders = response.headers();    for (int i = 0, size = responseHeaders.size(); i < size; i++) {      System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));    }    System.out.println(response.body().string());  }});

}

下面对以上代码进行一下说明:

要想异步执行网络请求,需要执行Call对象的enqueue方法,该方法接收一个okhttp3.Callback对象,enqueue方法不会阻塞当前线程,会新开一个工作线程,让实际的网络请求在工作线程中执行。一般情况下这个工作线程的名字以“Okhttp”开头,并包含连接的host信息,比如上面例子中的工作线程的name是"Okhttp http://publicobject.com/..."当异步请求成功后,会回调Callback对象的onResponse方法,在该方法中可以获取Response对象。当异步请求失败或者调用了Call对象的cancel方法时,会回调Callback对象的onFailure方法。onResponse和onFailure这两个方法都是在工作线程中执行的。

请求头和响应头

典型的HTTP请求头、响应头都是类似于Map

0 0
原创粉丝点击