okhttp 的使用

OkHttp 库的设计和实现的首要目标是高效。官网写着 适用于Android和Java应用程序的HTTP和HTTP / 2客户端

OkHttp是默认有效的HTTP客户端:

HTTP / 2支持允许同一主机的所有请求共享一个套接字。
连接池减少了请求延迟(如果HTTP / 2不可用)。
透明GZIP缩小了下载大小。
响应缓存完全避免网络重复请求。
当网络很麻烦时,OkHttp会坚持下去:它会默默地从常见的连接问题中恢复过来。如果您的服务有多个IP地址,如果第一次连接失败,OkHttp将尝试备用地址。这对IPv4 + IPv6和冗余数据中心托管的服务是必需的。OkHttp启动与现代TLS功能(SNI,ALPN)的新连接,并且如果握手失败则回退到TLS 1.0。

使用OkHttp很容易。其请求/响应API的设计具有流畅的构建器和不变性。它支持同步阻塞调用和带回调的异步调用。

OkHttp支持Android 2.3及以上版本。对于Java,最低要求是1.7。

GitHub 地址 点击这里

maven 加入

<dependency>
          <groupId>com.squareup.okhttp3</groupId>
          <artifactId>okhttp</artifactId>
          <version>3.10.0</version>
      </dependency>

代码

package com.nossdk.demo;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

import java.io.IOException;

public class okhttpdemo {


    // 创建 okHttpClient 对象
    OkHttpClient client = new OkHttpClient();

    // 创建一个 Request

    String run(String url) throws IOException {

        Request request = new Request.Builder().url(url).build();

        try (Response response = client.newCall(request).execute()) {
            return response.body().string();
        }
    }


    public static void main(String[] args) throws IOException {

        okhttpdemo httpdemo = new okhttpdemo();

        String respone = httpdemo.run("http://www.163.com");
        System.out.println(respone);
    }
}

得到如下结果

问题

try (Response response = client.newCall(request).execute()) {
               return response.body().string();
           }

这段报错

try-with-resources is not supported in -source 5

解决办法

设置当前模块的 Source Language Level:

File -> Project Structure -> Modules -> Sources -> Language Level

基本使用

HTTP GET

OkHttpClient client = new OkHttpClient();

String run(String url) throws IOException {
    Request request = new Request.Builder().url(url).build();
    Response response = client.newCall(request).execute();    if (response.isSuccessful()) {        return response.body().string();
    } else {        throw new IOException("Unexpected code " + response);
    }
}

Request是OkHttp中访问的请求,Builder是辅助类。Response即OkHttp中的响应。

Response 类

public boolean isSuccessful()
Returns true if the code is in [200..300),
 which means the request was successfully received, understood, and accepted.

response.body()返回ResponseBody类

可以方便的获取string

public final String string() throws IOException
Returns the response as a string decoded with the charset of the Content-Type header. If that header is either absent or lacks a charset,
 this will attempt to decode the response body as UTF-8.Throws:
IOException

当然也能获取到流的形式:

public final InputStream byteStream()
HTTP POST
POST提交Json数据
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
String post(String url, String json) throws IOException {
     RequestBody body = RequestBody.create(JSON, json);
      Request request = new Request.Builder()
      .url(url)
      .post(body)
      .build();
      Response response = client.newCall(request).execute();
    f (response.isSuccessful()) {
        return response.body().string();
    } else {
        throw new IOException("Unexpected code " + response);
    }
}

使用Request的post方法来提交请求体RequestBody

POST提交键值对
很多时候我们会需要通过POST方式把键值对数据传送到服务器。 OkHttp提供了很方便的方式来做这件事情。

OkHttpClient client = new OkHttpClient();
String post(String url, String json) throws IOException {

     RequestBody formBody = new FormEncodingBuilder()
    .add("platform", "android")
    .add("name", "bug")
    .add("subject", "XXXXXXXXXXXXXXX")
    .build();

      Request request = new Request.Builder()
      .url(url)
      .post(body)
      .build();

      Response response = client.newCall(request).execute();
    if (response.isSuccessful()) {
        return response.body().string();
    } else {
        throw new IOException("Unexpected code " + response);
    }
}

总结
通过上面的例子我们可以发现,OkHttp在很多时候使用都是很方便的,而且很多代码也有重复,因此特地整理了下面的工具类。

注意

  • OkHttp官方文档并不建议我们创建多个OkHttpClient,因此全局使用一个。 如果有需要,可以使用clone方法,再进行自定义。这点在后面的高级教程里会提到。

  • enqueue为OkHttp提供的异步方法,入门教程中并没有提到,后面的高级教程里会有解释。