溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何使用OkHttp網(wǎng)絡(luò)請求框架

發(fā)布時(shí)間:2021-10-21 09:30:46 來源:億速云 閱讀:115 作者:iii 欄目:編程語言

這篇文章主要介紹“如何使用OkHttp網(wǎng)絡(luò)請求框架”,在日常操作中,相信很多人在如何使用OkHttp網(wǎng)絡(luò)請求框架問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”如何使用OkHttp網(wǎng)絡(luò)請求框架”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

一、OkHttp介紹

??HTTP是現(xiàn)代應(yīng)用常用的一種交換數(shù)據(jù)和媒體的網(wǎng)絡(luò)方式,高效地使用HTTP能讓資源加載更快,節(jié)省帶寬。OkHttp是一個(gè)優(yōu)秀的網(wǎng)絡(luò)請求框架,它有以下默認(rèn)特性:

  • 支持HTTP/2,允許所有同一個(gè)主機(jī)地址的請求共享同一個(gè)socket連接

  • 連接池減少請求延時(shí)

  • 透明的GZIP壓縮減少響應(yīng)數(shù)據(jù)的大小

  • 緩存響應(yīng)內(nèi)容,避免一些完全重復(fù)的請求

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

引入maven依賴:

<!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp -->
<dependency>
	<groupid>com.squareup.okhttp3</groupid>
	<artifactid>okhttp</artifactid>
	<version>${laster.version}</version>
</dependency>

OkHttp 項(xiàng)目有如下模塊:

模塊內(nèi)容
okhttp實(shí)現(xiàn)OkHttp庫的模塊
okhttp-testsOkHttp庫單元測試的模塊
okhttp-android-support支持android平臺使用OkHttp庫的模塊
okhttp-apache實(shí)現(xiàn)ApacheHttpClient接口(下一版本會(huì)棄用)
okhttp-testing-support支持單元測試的模塊
okhttp-urlconnection實(shí)現(xiàn)HttpURLConnection接口(下一版本會(huì)棄用)
okhttp-ws支持WebSocket
okhttp-logging-interceptor實(shí)現(xiàn)Logging攔截器
okcurl實(shí)現(xiàn)OkCurl
mockwebserver腳本化WebServer,用于測試HTTP客戶端

OkHttp 項(xiàng)目父模塊中主要包含以下插件:

插件用途
maven-compiler-plugin編譯項(xiàng)目
maven-surefire-plugin執(zhí)行測試
maven-javadoc-plugin生成文檔
maven-release-plugin自動(dòng)化項(xiàng)目版本發(fā)布
maven-checkstyle-plugin檢測編碼風(fēng)格
animal-sniffer-maven-plugin檢測代碼API

官方介紹

github源碼

二、OkHttp 基本使用

2.1 進(jìn)行Get請求

使用OkHttp進(jìn)行Get請求只需要四步即可完成:

  1. 創(chuàng)建okHttpClient對象

    OkHttpClient client = new OkHttpClient();


  2. 構(gòu)造Request對象

    // 首先構(gòu)造一個(gè)Request對象,參數(shù)最起碼有個(gè)url,當(dāng)然可以通過Request.Builder設(shè)置更多的參數(shù)比如:header、method等
    Request request = new Request.Builder().get().url("https://api.github.com/users/dllwh").build();


  3. 將Request封裝為Call

    // 通過request的對象去構(gòu)造得到一個(gè)Call對象,類似于將請求封裝成了任務(wù)
    Call call = client.newCall(request);


  4. 根據(jù)需要調(diào)用同步或者異步請求方法

    // 同步調(diào)用,返回Response,需要這里會(huì)拋出IO異常
    Response response = call.execute();
    if (response.isSuccessful()) {
        System.out.println(response.body().string());
    }


    > 同步調(diào)用會(huì)阻塞主線程,直到 HTTP 響應(yīng)返回,對應(yīng) OKHTTP 中的 execute 方法,一般不適用。

    // 以異步的方式去執(zhí)行請求
    call.enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
    
        }
    
        @Override
        public void onResponse(Call call, final Response response) throws IOException {
            // http響應(yīng)行的code,如果訪問成功則返回200。這個(gè)不是服務(wù)器設(shè)置的,而是http協(xié)議中自帶的。
    				final int httpCode = response.code();
            ResponseBody responseBody = response.body();
            // 返回的字符串,只能調(diào)用一次,在第一次時(shí)有返回值,第二次再調(diào)用時(shí)將會(huì)返回null。
            final String res = responseBody.string();
            // 返回的二進(jìn)制字節(jié)數(shù)組
            final byte[] bytes = responseBody.bytes();
            // 返回的InputStream
            final InputStream inputStream = responseBody.byteStream();
        }
    });


    > 以異步調(diào)用的方式去執(zhí)行非阻塞式請求,它的執(zhí)行結(jié)果一般都是通過接口回調(diào)的方式告知調(diào)用者,它對應(yīng) OKHTTP 中的 enqueue 方法。

2.2 進(jìn)行Post請求

2.2.1 Post請求鍵值對

??很多時(shí)候我們會(huì)需要通過POST方式把鍵值對數(shù)據(jù)傳送到服務(wù)器,OkHttp提供了很方便的方式來做這件事情。使用OkHttp進(jìn)行Post請求和進(jìn)行Get請求很類似,只需要五步即可完成:

  1. 創(chuàng)建okHttpClient對象

    OkHttpClient client = new OkHttpClient();


  2. 構(gòu)建FormBody,傳入?yún)?shù)

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


    > post的參數(shù)是通過構(gòu)造一個(gè)FormBody通過鍵值對的方式來添加進(jìn)去的,其實(shí)post方法需要傳入的是一個(gè)RequestBody對象,用它來攜帶我們要提交的數(shù)據(jù),FormBodyRequestBody的子類。

  3. 構(gòu)建Request,將FormBody作為Post方法的參數(shù)傳入

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


  4. 將Request封裝為Call

    Call call = client.newCall(request);


  5. 根據(jù)需要調(diào)用同步或者異步請求方法。

    // 同步調(diào)用,返回Response,它對應(yīng) OKHTTP 中的 execute 方法,會(huì)拋出IO異常。
    Response response = call.execute();
    if (response.isSuccessful()) {
        System.out.println(response.body().string());
    }


    // 以異步的方式去執(zhí)行非阻塞式請求,它的執(zhí)行結(jié)果一般都是通過接口回調(diào)的方式告知調(diào)用者,它對應(yīng) 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. 創(chuàng)建okHttpClient對象

    OkHttpClient client = new OkHttpClient();


  2. 構(gòu)建RequestBody,傳入?yún)?shù)

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


    > 這種方式與前面的區(qū)別就是在構(gòu)造Request對象時(shí),需要多構(gòu)造一個(gè)RequestBody對象,用它來攜帶我們要提交的數(shù)據(jù)。在構(gòu)造 RequestBody 需要指定MediaType,用于描述請求/響應(yīng) body 的內(nèi)容類型。

  3. 構(gòu)建Request,將FormBody作為Post方法的參數(shù)傳入

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


  4. 將Request封裝為Call

    Call call = client.newCall(request);


  5. 根據(jù)需要調(diào)用同步或者異步請求方法。

    // 同步調(diào)用,返回Response,會(huì)拋出IO異常
    Response response = call.execute();
    if (response.isSuccessful()) {
        System.out.println(response.body().string());
    }


    /// 以異步的方式去執(zhí)行非阻塞式請求,它的執(zhí)行結(jié)果一般都是通過接口回調(diào)的方式告知調(diào)用者,它對應(yīng) 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請求提交表單

??我們在網(wǎng)頁上經(jīng)常會(huì)遇到用戶注冊的情況,需要你輸入用戶名、密碼(當(dāng)然還有其他參數(shù),這里僅僅舉例說明),這其實(shí)就是一個(gè)表單,那么接下來我們看看如何利用OkHttp來進(jìn)行表單提交。經(jīng)過上面的學(xué)習(xí),大家肯定也明白,主要的區(qū)別就在于構(gòu)造不同的RequestBody傳遞給post方法即可。這里我們會(huì)用到一個(gè)MuiltipartBody,這是RequestBody的一個(gè)子類,我們提交表單就是利用這個(gè)類來構(gòu)建一個(gè)RequestBody,下面的代碼我們會(huì)發(fā)送一個(gè)包含用戶民、密碼到服務(wù)端。

@Test
public void doPostForm() throws IOException {
	OkHttpClient okHttpClient = new OkHttpClient();
	okhttp3.MultipartBody.Builder builder = new MultipartBody.Builder();
	// 如果提交的是表單,一定要設(shè)置這句
	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 進(jìn)行文件上傳、下載

2.3.1 Post請求上傳文件

??接下來我們在介紹一個(gè)可以構(gòu)造RequestBody的Builder,叫做MultipartBuilder。當(dāng)我們需要做類似于表單上傳的時(shí)候,就可以使用它來構(gòu)造我們的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 &lt; headers.size(); i++) {
        System.out.println(headers.name(i) + ": " + headers.value(i));
    }
    System.out.println(response.body().string());
}

2.4 HTTP頭屬性配置

??典型的HTTP頭就是像是一個(gè) Map<string, string> ,每個(gè)字段都有一個(gè)或沒有值。
??當(dāng)寫請求頭的時(shí)候,使用header(name, value)可以設(shè)置唯一的name、value。如果已經(jīng)有值,舊的將被移除,然后添加新的。使用addHeader(name, value)可以添加多值(添加,不移除已有的)。
??當(dāng)讀取響應(yīng)頭時(shí),使用header(name)返回最后出現(xiàn)的name、value。通常情況這也是唯一的name、value。如果沒有值,那么header(name)將返回null。如果想讀取字段對應(yīng)的所有值,使用headers(name)會(huì)返回一個(gè)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"));
}

三、總結(jié)

??通過上面的例子我們可以發(fā)現(xiàn),OkHttp在很多時(shí)候使用都是很方便的,而且很多代碼也有重復(fù),而且 OkHttp 官方文檔并不建議我們創(chuàng)建多個(gè)OkHttpClient,因此全局可以使用一個(gè)。

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

/**
 * 把今天最好的表現(xiàn)當(dāng)作明天最新的起點(diǎn)..~
 * <p>
 * Today the best performance as tomorrow newest starter!
 *
 * @類描述: OkHttp 基本使用
 * @author: <a href="mailto:duleilewuhen@sina.com">獨(dú)淚了無痕</a>
 * @創(chuàng)建時(shí)間: 2020-12-22 11:54
 * @版本: V 1.0.1
 * @since: JDK 1.8
 * @see <a href="https://square.github.io/okhttp/">官方介紹</a>
 */
@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<string, object> 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<string, object> 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);
    }

    /**
     * 同步請求,不會(huì)開始異步線程
     *
     * @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);
    }

    /**
     * 開啟異步線程訪問網(wǎng)絡(luò), 且不在意返回結(jié)果(實(shí)現(xiàn)空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());
                }
            }

        });
    }
}

到此,關(guān)于“如何使用OkHttp網(wǎng)絡(luò)請求框架”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI