您好,登錄后才能下訂單哦!
這篇文章主要介紹“如何使用OkHttp網絡請求框架”,在日常操作中,相信很多人在如何使用OkHttp網絡請求框架問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”如何使用OkHttp網絡請求框架”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
??HTTP是現代應用常用的一種交換數據和媒體的網絡方式,高效地使用HTTP能讓資源加載更快,節省帶寬。OkHttp是一個優秀的網絡請求框架,它有以下默認特性:
支持HTTP/2,允許所有同一個主機地址的請求共享同一個socket連接
連接池減少請求延時
透明的GZIP壓縮減少響應數據的大小
緩存響應內容,避免一些完全重復的請求
:@@@. .@@@@@@@: +@@ `@@ @@` @@ @@ .@@@@'@@@@: +@@ `@@ @@` @@ @@ @@@ @@@ +@@ `@@ @@` @@ @@ .@@ @@: +@@ @@@ `@@ @@` @@@@@@ @@@@@@ @@;@@@@@ @@@ @@@ +@@ @@@ `@@ @@` @@@@@@ @@@@@@ @@@@@@@@@ @@@ @@@ +@@ @@@ `@@@@@@@@@@` @@ @@ @@@ :@@ @@@ @@@ +@@@@@ `@@@@@@@@@@` @@ @@ @@# @@+ @@@ @@@ +@@@@@+ `@@ @@` @@ @@ @@: @@# @@: .@@` +@@@+@@ `@@ @@` @@ @@ @@# @@+ @@@. .@@@ +@@ @@@ `@@ @@` @@ @@ @@@ ,@@ @@@@@@@@@ +@@ @@@ `@@ @@` @@@@ @@@@ @@@@#@@@@ @@@@@@@ +@@ #@@ `@@ @@` @@@@: @@@@: @@'@@@@@ @@: @@: @@:
引入maven依賴:
<!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp --> <dependency> <groupid>com.squareup.okhttp3</groupid> <artifactid>okhttp</artifactid> <version>${laster.version}</version> </dependency>
OkHttp 項目有如下模塊:
模塊 | 內容 |
---|---|
okhttp | 實現OkHttp庫的模塊 |
okhttp-tests | OkHttp庫單元測試的模塊 |
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進行Get
請求只需要四步即可完成:
創建okHttpClient對象
OkHttpClient client = new OkHttpClient();
構造Request對象
// 首先構造一個Request對象,參數最起碼有個url,當然可以通過Request.Builder設置更多的參數比如:header、method等 Request request = new Request.Builder().get().url("https://api.github.com/users/dllwh").build();
將Request封裝為Call
// 通過request的對象去構造得到一個Call對象,類似于將請求封裝成了任務 Call call = client.newCall(request);
根據需要調用同步或者異步請求方法
// 同步調用,返回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 方法。
??很多時候我們會需要通過POST方式把鍵值對數據傳送到服務器,OkHttp提供了很方便的方式來做這件事情。使用OkHttp進行Post
請求和進行Get
請求很類似,只需要五步即可完成:
創建okHttpClient對象
OkHttpClient client = new OkHttpClient();
構建FormBody,傳入參數
okhttp3.FormBody.Builder builder = new FormBody.Builder(); builder.add("username", "admin"); builder.add("password", "admin"); FormBody formBody = builder.build();
> post的參數是通過構造一個FormBody
通過鍵值對的方式來添加進去的,其實post方法需要傳入的是一個RequestBody
對象,用它來攜帶我們要提交的數據,FormBody
是RequestBody
的子類。
構建Request,將FormBody作為Post方法的參數傳入
Request request = new Request.Builder().url(url).post(formBody).build();
將Request封裝為Call
Call call = client.newCall(request);
根據需要調用同步或者異步請求方法。
// 同步調用,返回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()) { } } });
創建okHttpClient對象
OkHttpClient client = new OkHttpClient();
構建RequestBody,傳入參數
MediaType mediaType = MediaType.parse("application/json;charset=UTF-8"); RequestBody requestBody = RequestBody.create(mediaType, "{username:admin;password:admin}");
> 這種方式與前面的區別就是在構造Request對象時,需要多構造一個RequestBody對象,用它來攜帶我們要提交的數據。在構造 RequestBody
需要指定MediaType
,用于描述請求/響應 body
的內容類型。
構建Request,將FormBody作為Post方法的參數傳入
Request request = new Request.Builder().url("http://www.jianshu.com/").post(requestBody).build();
將Request封裝為Call
Call call = client.newCall(request);
根據需要調用同步或者異步請求方法。
// 同步調用,返回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()) { } } });
??我們在網頁上經常會遇到用戶注冊的情況,需要你輸入用戶名、密碼(當然還有其他參數,這里僅僅舉例說明),這其實就是一個表單,那么接下來我們看看如何利用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()); }
??接下來我們在介紹一個可以構造RequestBody的Builder,叫做MultipartBuilder
。當我們需要做類似于表單上傳的時候,就可以使用它來構造我們的requestBody。
@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()); }
??典型的HTTP頭就是像是一個 Map<string, string>
,每個字段都有一個或沒有值。
??當寫請求頭的時候,使用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; /** * 把今天最好的表現當作明天最新的起點..~ * <p> * Today the best performance as tomorrow newest starter! * * @類描述: OkHttp 基本使用 * @author: <a href="mailto:duleilewuhen@sina.com">獨淚了無痕</a> * @創建時間: 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); } /** * 同步請求,不會開始異步線程 * * @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網絡請求框架”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。