您的位置:

OkHttp3:轻量级、高效、易用的Http客户端程序库

一、简介

OkHttp3是一个轻量级的HTTP客户端程序库,被广泛应用于Android、Java和Kotlin语言的应用程序中。OkHttp3比传统的HttpURLConnection更加高效、简单易用、功能丰富,尤其适合于请求网络资源,并且可以用于处理REST API的调用。

OkHttp3的主要特点:

  • 使用流行的Okio库来进行缓存和输入/输出
  • 支持同步和异步请求
  • 支持请求方式(GET、POST等)、请求头、请求体、响应、拦截器、缓存等多个功能
  • 支持连接池和GZIP等自动压缩机制

在下面,我们将会通过多个方面来阐述OkHttp3的主要特点和使用方法。

二、网络请求

OkHttp3支持同步和异步的网络请求。其中同步请求在当前线程中进行网络访问,由于会阻塞当前线程,不推荐在Android的主线程中进行;而异步请求则是在新的线程中进行网络访问。在进行网络请求时,通常需要手动编写网络请求参数、请求头、请求体等信息。

1、同步请求

在进行同步请求时,需要获取一个OkHttpClient对象和一个Request对象。OkHttpClient是发出HTTP请求的入口,而Request对象则封装了HTTP请求的参数、请求头、请求体等信息。

  OkHttpClient client = new OkHttpClient();  
  Request request = new Request.Builder()  
          .url("http://www.example.com")  
          .build();  
  Response response = client.newCall(request).execute();

在上面的代码中,我们首先创建了一个OkHttpClient对象,接着通过Request.Builder添加了url信息,最后使用client.newCall发起同步请求,获取Response对象

2、异步请求

在进行异步请求时,也需要获取一个OkHttpClient对象和一个Request对象。不同的是,异步请求需要注册一个回调方法来接收响应结果。

  OkHttpClient client = new OkHttpClient();  
  Request request = new Request.Builder()  
          .url("http://www.example.com")  
          .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 {  
          System.out.println(response.body().string());  
      }  
  });

在上面的代码中,我们同样使用Request.Builder添加了url信息,接着使用client.newCall发起异步请求,并且在enqueue方法中注册了一个回调函数,当异步请求完成后,会自动回调onResponse方法。

三、请求头和请求体

OkHttp3支持设置请求头和请求体,可以使用Request.Builder添加请求头,使用RequestBody类来添加请求体。以下是添加请求头和请求体的示例:

  RequestBody formBody = new FormBody.Builder()  
          .add("username", "admin")  
          .add("password", "admin")  
          .build();  

  Request request = new Request.Builder()  
          .url("http://www.example.com")  
          .header("User-Agent", "OkHttp Headers.java")  
          .addHeader("Accept", "application/json; q=0.5")  
          .addHeader("Accept", "application/vnd.github.v3+json")  
          .post(formBody)  
          .build(); 

在上面的代码中,我们使用FormBody构建了一个请求体,并且通过header和addHeader方法添加了两个请求头。

四、响应

OkHttp3的响应类是Response,其中包含响应状态码、响应头和响应体等信息。

以下是一个获得响应体的示例:

  OkHttpClient client = new OkHttpClient();  
  Request request = new Request.Builder()  
          .url("http://www.example.com")  
          .build();  
  Response response = null;  
  try {  
      response = client.newCall(request).execute();  
      if (response.isSuccessful()) {  
          System.out.println(response.body().string());  
      } else {  
          throw new IOException("Unexpected code " + response);  
      }  
  } catch (IOException e) {  
      e.printStackTrace();  
  } finally {  
      if (response != null) {  
          response.close();  
      }  
  }

在上面的代码中,我们通过response.isSuccessful()方法判断请求是否成功,并且通过response.body()获得了响应体,最后需要手动关闭响应。

五、拦截器

拦截器是OkHttp3的重要特性之一,可以在请求和响应的过程中拦截、修改和处理请求头、响应头和响应体等信息。通过实现Interceptor接口,就可以自定义拦截器,可以添加多个拦截器。

以下是一个添加拦截器的示例:

  OkHttpClient client = new OkHttpClient.Builder()  
          .addInterceptor(new Interceptor() {  
              @Override  
              public Response intercept(Chain chain) throws IOException {  
                  Request request = chain.request();  

                  long t1 = System.nanoTime();  
                  System.out.println(String.format("Sending request %s on %s%n%s", request.url(), chain.connection(), request.headers()));  

                  Response response = chain.proceed(request);  

                  long t2 = System.nanoTime();  
                  System.out.println(String.format("Received response for %s in %.1fms%n%s", response.request().url(), (t2 - t1) / 1e6d, response.headers()));  

                  return response;  
              }  
          })  
          .build();  
  Request request = new Request.Builder()  
          .url("http://www.example.com")  
          .header("User-Agent", "OkHttp Headers.java")  
          .addHeader("Accept", "application/json; q=0.5")  
          .addHeader("Accept", "application/vnd.github.v3+json")  
          .build();  
  try {  
      Response response = client.newCall(request).execute();  
      System.out.println(response.body().string());  
  } catch (IOException e) {  
      e.printStackTrace();  
  }

在上面的代码中,我们添加了一个Interceptor拦截器,用于输出请求和响应信息,在请求和响应完成后,都会在控制台输出相应的信息。

六、缓存

OkHttp3支持缓存,可以快速读取缓存中的响应,而不需要进行网络请求。有两种方式来设置缓存,一种是设置无网络缓存,另一种是设置有网络缓存。无网络缓存是指在没有网络的情况下也可以从缓存中读取数据,而有网络缓存是指在有网络的情况下,将响应数据保存到缓存中。

以下是添加网络缓存的示例:

  File cacheDir = new File(context.getExternalCacheDir(), "cache");  
  Cache cache = new Cache(cacheDir, CACHE_SIZE);  
  OkHttpClient client = new OkHttpClient.Builder()  
          .cache(cache)  
          .build();  
  Request request = new Request.Builder()  
          .url("http://www.example.com")  
          .header("User-Agent", "OkHttp Headers.java")  
          .addHeader("Accept", "application/json; q=0.5")  
          .addHeader("Accept", "application/vnd.github.v3+json")  
          .build();  
  try {  
      Response response = client.newCall(request).execute();  
      if (response.isSuccessful()) {  
          System.out.println("Response from cache");  
      } else {  
          throw new IOException("Unexpected code " + response);  
      }  
  } catch (IOException e) {  
      e.printStackTrace();  
  }

在上面的代码中,我们首先创建了一个cache目录用于存放缓存,然后通过Cache构造函数创建一个缓存对象,最后在OkHttpClient.Builder中添加缓存对象。在发起请求时,如果有缓存,则会从缓存中读取数据。

七、总结

OkHttp3是一个高性能、轻量级、简单易用的Http客户端程序库,被广泛应用于Android、Java和Kotlin语言的应用程序中。OkHttp3具有很多好用的特性,如支持同步/异步请求、请求头、请求体、响应、拦截器、缓存等功能,开发者可以根据需要自由配置。在实际开发中,OkHttp3可以用于请求网络资源,也可以用于处理REST API的调用等,相对于传统的HttpURLConnection等工具,使用OkHttp3可以更加轻松地完成网络请求的任务。