如何使用OkHttp网络请求框架

这篇文章主要介绍“如何使用OkHttp网络请求框架”,在日常操作中,相信很多人在如何使用OkHttp网络请求框架问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何使用OkHttp网络请求框架”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

我们提供的服务有:网站制作、成都做网站、微信公众号开发、网站优化、网站认证、桥西ssl等。为1000+企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的桥西网站制作公司

一、OkHttp介绍

  HTTP是现代应用常用的一种交换数据和媒体的网络方式,高效地使用HTTP能让资源加载更快,节省带宽。OkHttp是一个优秀的网络请求框架,它有以下默认特性:

  • 支持HTTP/2,允许所有同一个主机地址的请求共享同一个socket连接

  • 连接池减少请求延时

  • 透明的GZIP压缩减少响应数据的大小

  • 缓存响应内容,避免一些完全重复的请求

     :@@@.
   .@@@@@@@:   +@@       `@@      @@`   @@     @@
  .@@@@'@@@@:  +@@       `@@      @@`   @@     @@
  @@@     @@@  +@@       `@@      @@`   @@     @@
 .@@       @@: +@@   @@@ `@@      @@` @@@@@@ @@@@@@  @@;@@@@@
 @@@       @@@ +@@  @@@  `@@      @@` @@@@@@ @@@@@@  @@@@@@@@@
 @@@       @@@ +@@ @@@   `@@@@@@@@@@`   @@     @@    @@@   :@@
 @@@       @@@ +@@@@@    `@@@@@@@@@@`   @@     @@    @@#    @@+
 @@@       @@@ +@@@@@+   `@@      @@`   @@     @@    @@:    @@#
  @@:     .@@` +@@@+@@   `@@      @@`   @@     @@    @@#    @@+
  @@@.   .@@@  +@@  @@@  `@@      @@`   @@     @@    @@@   ,@@
   @@@@@@@@@   +@@   @@@ `@@      @@`   @@@@   @@@@  @@@@#@@@@
    @@@@@@@    +@@   #@@ `@@      @@`   @@@@:  @@@@: @@'@@@@@
                                                     @@:
                                                     @@:
                                                     @@:

引入maven依赖:



	com.squareup.okhttp3
	okhttp
	${laster.version}

OkHttp 项目有如下模块:

模块内容
okhttp实现OkHttp库的模块
okhttp-testsOkHttp库单元测试的模块
okhttp-android-support支持android平台使用OkHttp库的模块
okhttp-apache实现ApacheHttpClient接口(下一版本会弃用)
okhttp-testing-support支持单元测试的模块
okhttp-urlconnection实现HttpURLConnection接口(下一版本会弃用)
okhttp-ws支持WebSocket
okhttp-logging-interceptor实现Logging拦截器
okcurl实现OkCurl
mockwebserver脚本化WebServer,用于测试HTTP客户端

OkHttp 项目父模块中主要包含以下插件:

插件用途
maven-compiler-plugin编译项目
maven-surefire-plugin执行测试
maven-javadoc-plugin生成文档
maven-release-plugin自动化项目版本发布
maven-checkstyle-plugin检测编码风格
animal-sniffer-maven-plugin检测代码API

官方介绍

github源码

二、OkHttp 基本使用

2.1 进行Get请求

使用OkHttp进行Get请求只需要四步即可完成:

  1. 创建okHttpClient对象

    OkHttpClient client = new OkHttpClient();

  2. 构造Request对象

    // 首先构造一个Request对象,参数最起码有个url,当然可以通过Request.Builder设置更多的参数比如:header、method等
    Request request = new Request.Builder().get().url("https://api.github.com/users/dllwh").build();

  3. 将Request封装为Call

    // 通过request的对象去构造得到一个Call对象,类似于将请求封装成了任务
    Call call = client.newCall(request);

  4. 根据需要调用同步或者异步请求方法

    // 同步调用,返回Response,需要这里会抛出IO异常
    Response response = call.execute();
    if (response.isSuccessful()) {
        System.out.println(response.body().string());
    }

    > 同步调用会阻塞主线程,直到 HTTP 响应返回,对应 OKHTTP 中的 execute 方法,一般不适用。

    // 以异步的方式去执行请求
    call.enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
    
        }
    
        @Override
        public void onResponse(Call call, final Response response) throws IOException {
            // http响应行的code,如果访问成功则返回200。这个不是服务器设置的,而是http协议中自带的。
    				final int httpCode = response.code();
            ResponseBody responseBody = response.body();
            // 返回的字符串,只能调用一次,在第一次时有返回值,第二次再调用时将会返回null。
            final String res = responseBody.string();
            // 返回的二进制字节数组
            final byte[] bytes = responseBody.bytes();
            // 返回的InputStream
            final InputStream inputStream = responseBody.byteStream();
        }
    });

    > 以异步调用的方式去执行非阻塞式请求,它的执行结果一般都是通过接口回调的方式告知调用者,它对应 OKHTTP 中的 enqueue 方法。

2.2 进行Post请求

2.2.1 Post请求键值对

  很多时候我们会需要通过POST方式把键值对数据传送到服务器,OkHttp提供了很方便的方式来做这件事情。使用OkHttp进行Post请求和进行Get请求很类似,只需要五步即可完成:

  1. 创建okHttpClient对象

    OkHttpClient client = new OkHttpClient();

  2. 构建FormBody,传入参数

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

    > post的参数是通过构造一个FormBody通过键值对的方式来添加进去的,其实post方法需要传入的是一个RequestBody对象,用它来携带我们要提交的数据,FormBodyRequestBody的子类。

  3. 构建Request,将FormBody作为Post方法的参数传入

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

  4. 将Request封装为Call

    Call call = client.newCall(request);

  5. 根据需要调用同步或者异步请求方法。

    // 同步调用,返回Response,它对应 OKHTTP 中的 execute 方法,会抛出IO异常。
    Response response = call.execute();
    if (response.isSuccessful()) {
        System.out.println(response.body().string());
    }

    // 以异步的方式去执行非阻塞式请求,它的执行结果一般都是通过接口回调的方式告知调用者,它对应 OKHTTP 中的 enqueue 方法。
    call.enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
    
        }
    
        @Override
        public void onResponse(Call call, final Response response) throws IOException {
        	if (response.isSuccessful()) {
    
            }
        }
    });

2.2.2 Post请求提交Json

  1. 创建okHttpClient对象

    OkHttpClient client = new OkHttpClient();

  2. 构建RequestBody,传入参数

    MediaType mediaType = MediaType.parse("application/json;charset=UTF-8");
    RequestBody requestBody = RequestBody.create(mediaType, "{username:admin;password:admin}");

    > 这种方式与前面的区别就是在构造Request对象时,需要多构造一个RequestBody对象,用它来携带我们要提交的数据。在构造 RequestBody 需要指定MediaType,用于描述请求/响应 body 的内容类型。

  3. 构建Request,将FormBody作为Post方法的参数传入

    Request request = new Request.Builder().url("http://www.jianshu.com/").post(requestBody).build();

  4. 将Request封装为Call

    Call call = client.newCall(request);

  5. 根据需要调用同步或者异步请求方法。

    // 同步调用,返回Response,会抛出IO异常
    Response response = call.execute();
    if (response.isSuccessful()) {
        System.out.println(response.body().string());
    }

    /// 以异步的方式去执行非阻塞式请求,它的执行结果一般都是通过接口回调的方式告知调用者,它对应 OKHTTP 中的 enqueue 方法。
    call.enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
    
        }
    
        @Override
        public void onResponse(Call call, final Response response) throws IOException {
            if (response.isSuccessful()) {
    
            }
        }
    });

2.2.3 Post请求提交表单

  我们在网页上经常会遇到用户注册的情况,需要你输入用户名、密码(当然还有其他参数,这里仅仅举例说明),这其实就是一个表单,那么接下来我们看看如何利用OkHttp来进行表单提交。经过上面的学习,大家肯定也明白,主要的区别就在于构造不同的RequestBody传递给post方法即可。这里我们会用到一个MuiltipartBody,这是RequestBody的一个子类,我们提交表单就是利用这个类来构建一个RequestBody,下面的代码我们会发送一个包含用户民、密码到服务端。

@Test
public void doPostForm() throws IOException {
	OkHttpClient okHttpClient = new OkHttpClient();
	okhttp3.MultipartBody.Builder builder = new MultipartBody.Builder();
	// 如果提交的是表单,一定要设置这句
	builder.setType(MultipartBody.FORM);
	builder.addFormDataPart("username", "admin");
	builder.addFormDataPart("password", "admin");
	RequestBody requestBody = builder.build();

	Request request = new Request.Builder().url("https://en.wikipedia.org/w/index.php").post(requestBody).build();
	Response response = okHttpClient.newCall(request).execute();
	if (!response.isSuccessful()) {
		throw new IOException("Unexpected code " + response);
	}
	System.out.println(response.body().string());
}

2.3 进行文件上传、下载

2.3.1 Post请求上传文件

  接下来我们在介绍一个可以构造RequestBody的Builder,叫做MultipartBuilder。当我们需要做类似于表单上传的时候,就可以使用它来构造我们的requestBody。

2.3.2 get请求下载文件

@Test
public void doGetFilePro() {
    OkHttpClient okHttpClient = new OkHttpClient();
    Request request = new Request.Builder()
        .url("http://publicobject.com/helloworld.txt")
        .build();
    Response response = okHttpClient.newCall(request).execute();
    if (!response.isSuccessful()) {
        throw new IOException("Unexpected code " + response);
    }
    Headers headers = response.headers();
    for (int i = 0; i < headers.size(); i++) {
        System.out.println(headers.name(i) + ": " + headers.value(i));
    }
    System.out.println(response.body().string());
}

2.4 HTTP头属性配置

  典型的HTTP头就是像是一个 Map ,每个字段都有一个或没有值。
  当写请求头的时候,使用header(name, value)可以设置唯一的name、value。如果已经有值,旧的将被移除,然后添加新的。使用addHeader(name, value)可以添加多值(添加,不移除已有的)。
  当读取响应头时,使用header(name)返回最后出现的name、value。通常情况这也是唯一的name、value。如果没有值,那么header(name)将返回null。如果想读取字段对应的所有值,使用headers(name)会返回一个list。

@Test
public void doHeader() throws IOException {
    OkHttpClient okHttpClient = new OkHttpClient();
    Request request = new Request.Builder()
            .url("https://api.github.com/repos/square/okhttp/issues")
            .header("User-Agent", "OkHttp Headers.java")
            .addHeader("Accept", "application/json; q=0.5")
            .addHeader("Accept", "application/vnd.github.v3+json")
            .build();
    Response response = okHttpClient.newCall(request).execute();
    if (!response.isSuccessful()) {
        throw new IOException("Unexpected code " + response);
    }
    System.out.println("Server: " + response.header("Server"));
    System.out.println("Date: " + response.header("Date"));
    System.out.println("Vary: " + response.headers("Vary"));
}

三、总结

  通过上面的例子我们可以发现,OkHttp在很多时候使用都是很方便的,而且很多代码也有重复,而且 OkHttp官方文档并不建议我们创建多个OkHttpClient,因此全局可以使用一个。

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import java.io.IOException;
import java.util.Map;

/**
 * 把今天最好的表现当作明天最新的起点..~
 * 

 * Today the best performance as tomorrow newest starter!  *  * @类描述: OkHttp 基本使用  * @author: 独泪了无痕  * @创建时间: 2020-12-22 11:54  * @版本: V 1.0.1  * @since: JDK 1.8  * @see 官方介绍  */ @Slf4j public final class OkHttpHelper {     static ObjectMapper mapper = new ObjectMapper();     /**      * 获取操作类      */     private static final OkHttpClient okHttpClient = new OkHttpClient();     private static final String CHARSET_NAME = "UTF-8";     private static final MediaType JSONMediaType = MediaType.parse("application/json;charset=UTF-8");     /**      * 同步get方式请求      *      * @param url      * @return      * @throws IOException      */     public static String doGet(String url) throws IOException {         Request request = new Request.Builder().get().url(url).build();         Call call = okHttpClient.newCall(request);         return execute(request);     }     /**      * 异步get方式请求      *      * @param url      * @return      * @throws IOException      */     public static void doSyncGet(String url) throws IOException {         Request request = new Request.Builder().get().url(url).build();         Call call = okHttpClient.newCall(request);         enqueue(request);     }     /**      * 同步post方式请求      */     public static String doPost(String url, Map params) throws IOException {         RequestBody requestBody = RequestBody.create(JSONMediaType, mapper.writeValueAsString(params));         Request.Builder builder = new Request.Builder();         Request request = builder.url(url).post(requestBody).build();         log.info("do post request and url[{}]", mapper.writeValueAsString(request));         return execute(request);     }     /**      * 同步post方式请求      */     public static String doPost(String url, String params) throws IOException {         RequestBody requestBody = RequestBody.create(JSONMediaType, params);         Request.Builder builder = new Request.Builder();         Request request = builder.url(url).post(requestBody).build();         log.info("do post request and url[{}]", mapper.writeValueAsString(request));         return execute(request);     }     /**      * 异步post方式请求      */     public static void doSyncPost(String url, String params) {         RequestBody body = RequestBody.create(JSONMediaType, params);         Request request = new Request.Builder().url(url).post(body).build();         enqueue(request);     }     public static String doPostJSON(String url, Map params, Headers headers) throws IOException {         RequestBody requestBody = RequestBody.create(JSONMediaType, mapper.writeValueAsString(params));         Request.Builder builder = new Request.Builder();         Request request = builder.url(url).post(requestBody).headers(headers).build();         log.info("do post request and url[{}]", mapper.writeValueAsString(request));         return execute(request);     }     /**      * 同步请求,不会开始异步线程      *      * @param request      * @return      * @throws IOException      */     private static String execute(Request request) throws IOException {         log.info("请求开始:请求地址为:{}", request.url());         Response response = okHttpClient.newCall(request).execute();         if (response.isSuccessful()) {             String res = response.body().string();             log.info("请求返回:{}", res);             return res;         } else {             throw new IOException("Unexpected code " + response);         }     }     /**      * 开启异步线程访问      *      * @param request      * @param responseCallback      */     public static void enqueue(Request request, Callback responseCallback) {         okHttpClient.newCall(request).enqueue(responseCallback);     }     /**      * 开启异步线程访问网络, 且不在意返回结果(实现空callback)      *      * @param request      */     private static void enqueue(Request request) {         okHttpClient.newCall(request).enqueue(new Callback() {             @Override             public void onFailure(Call call, IOException e) {                 log.error("",e);             }             @Override             public void onResponse(Call call, Response response) throws IOException {ßß                 if (response.isSuccessful()) {                     log.info("Successful data acquisition . . . ");                     log.info("response.code()==" + response.code());                     log.info("response.body().string()==" + response.body().string());                 }             }         });     } }

到此,关于“如何使用OkHttp网络请求框架”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注创新互联网站,小编会继续努力为大家带来更多实用的文章!


分享文章:如何使用OkHttp网络请求框架
地址分享:http://scyanting.com/article/gsgjig.html