Okhttp3源碼解析(2)-Request分析

来源:https://www.cnblogs.com/qinzishuai/archive/2019/08/23/11401790.html
-Advertisement-
Play Games

### 前言 前面我們講了 [Okhttp的基本用法](https://www.jianshu.com/p/8e404d9c160f) [Okhttp3源碼解析(1)-OkHttpClient分析](https://www.jianshu.com/p/bf1d01b79ce7) 今天主要分析下Req ...


### 前言 前面我們講了 [Okhttp的基本用法](https://www.jianshu.com/p/8e404d9c160f) [Okhttp3源碼解析(1)-OkHttpClient分析](https://www.jianshu.com/p/bf1d01b79ce7) 今天主要分析下Request源碼! ### Request初始化 當我們構建完OkHttpClient對象,需要構造Request對象,構造方式如下: ###### 1.Get請求 ``` final Request request=new Request.Builder() .url("https://www.wanandroid.com/navi/json") .get() .build(); ``` ###### 2.POST請求 拿POST提交表單請求,這時就需要聲明一個RequestBody對象了 ``` RequestBody requestBody = new FormBody.Builder() .add("username", "qinzishuai") .add("password", "123456") .build(); Request request = new Request.Builder() .url("https://www.wanandroid.com/user/login") .post(requestBody) .build(); ``` 看到上面代碼是不是很熟悉?和OkHttpClient很相似, 沒錯 Request 的構建也是Builder模式! ![](https://img2018.cnblogs.com/blog/1312938/201908/1312938-20190823180241877-899976016.png) 我們點擊Request源碼進去,果然 其中有靜態的Builder內部類: ![](https://img2018.cnblogs.com/blog/1312938/201908/1312938-20190823180242273-1916386988.png) 然後我們查一下**Request在初始化時配置了哪些參數???** ``` public static class Builder { HttpUrl url; String method; Headers.Builder headers; RequestBody body; public Builder() { this.method = "GET"; this.headers = new Headers.Builder(); } //省略部分代碼 public Request build() { if (url == null) throw new IllegalStateException("url == null"); return new Request(this); } } ``` 從代碼看到了 如果沒有聲明,預設是Get請求 ` this.method = "GET"` ,至於`url`等欄位需要我們自己去配置: ###### HttpUrl 請求訪問的url ,可以傳String與URL 具體方法如下: ``` public Builder url(String url) { if (url == null) throw new NullPointerException("url == null"); // Silently replace web socket URLs with HTTP URLs. if (url.regionMatches(true, 0, "ws:", 0, 3)) { url = "http:" + url.substring(3); } else if (url.regionMatches(true, 0, "wss:", 0, 4)) { url = "https:" + url.substring(4); } return url(HttpUrl.get(url)); } public Builder url(URL url) { if (url == null) throw new NullPointerException("url == null"); return url(HttpUrl.get(url.toString())); } ``` ###### method 請求類型 `String method `,支持多種請求類型 ``` public Builder get() { return method("GET", null); } public Builder head() { return method("HEAD", null); } public Builder post(RequestBody body) { return method("POST", body); } public Builder delete(@Nullable RequestBody body) { return method("DELETE", body); } public Builder delete() { return delete(Util.EMPTY_REQUEST); } public Builder put(RequestBody body) { return method("PUT", body); } public Builder patch(RequestBody body) { return method("PATCH", body); } ``` ###### Headers `Headers.Builder ` Http消息的頭欄位 前面看到了, **我們在初始化Request的時候 同時初始化了headers**, ` this.headers = new Headers.Builder()` 可以通過 `header ` `addHeader ` `removeHeader ` ` headers ` 方法做一些操作 ``` public Builder header(String name, String value) { headers.set(name, value); return this; } public Builder addHeader(String name, String value) { headers.add(name, value); return this; } public Builder removeHeader(String name) { headers.removeAll(name); return this; } public Builder headers(Headers headers) { this.headers = headers.newBuilder(); return this; } ``` ###### body RequestBody類型,它是抽象類, 有些請求需要我們傳入body實例 ,我們在通過源碼來看一下: 如果是GET請求,body對象傳的是null **Get與head方法不能傳body對象 ,其他method是可以的** ![](https://img2018.cnblogs.com/blog/1312938/201908/1312938-20190823180242513-433063641.png) 如果是POST請求,就需要我們去設定了 ![](https://img2018.cnblogs.com/blog/1312938/201908/1312938-20190823180242695-600270897.png) ### RequestBody解析 首先我們看一下RequestBody如何初始化??拿提交表單舉例: ``` RequestBody requestBody = new FormBody.Builder() .add("username", "qinzishuai") .add("password", "000000") .build(); ``` 不出所料,也是Builder模式,而且`RequestBody` 是抽象類, `FormBody`是`RequestBody`的其中一種實現類 ,另一個實現類是`MultipartBody` RequestBody源碼如下: ``` public abstract class RequestBody { /** Returns the Content-Type header for this body. */ public abstract @Nullable MediaType contentType(); /** * Returns the number of bytes that will be written to {@code sink} in a call to {@link #writeTo}, * or -1 if that count is unknown. */ public long contentLength() throws IOException { return -1; } /** Writes the content of this request to {@code sink}. */ public abstract void writeTo(BufferedSink sink) throws IOException; /** * Returns a new request body that transmits {@code content}. If {@code contentType} is non-null * and lacks a charset, this will use UTF-8. */ public static RequestBody create(@Nullable MediaType contentType, String content) { Charset charset = Util.UTF_8; if (contentType != null) { charset = contentType.charset(); if (charset == null) { charset = Util.UTF_8; contentType = MediaType.parse(contentType + "; charset=utf-8"); } } byte[] bytes = content.getBytes(charset); return create(contentType, bytes); } /** Returns a new request body that transmits {@code content}. */ public static RequestBody create( final @Nullable MediaType contentType, final ByteString content) { return new RequestBody() { @Override public @Nullable MediaType contentType() { return contentType; } @Override public long contentLength() throws IOException { return content.size(); } @Override public void writeTo(BufferedSink sink) throws IOException { sink.write(content); } }; } /** Returns a new request body that transmits {@code content}. */ public static RequestBody create(final @Nullable MediaType contentType, final byte[] content) { return create(contentType, content, 0, content.length); } //省略部分代碼... } ``` 核心方法有三個: - contentType()//數據類型 - contentLength()//數據長度 - writeTo(BufferedSink sink) //寫操作 今天就講到這裡,希望對大家有所幫助... 大家可以關註我的微信公眾號:「秦子帥」一個有質量、有態度的公眾號! ![公眾號](https://img2018.cnblogs.com/blog/1312938/201908/1312938-20190823180242882-2108811045.jpg)
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 當hdfs文件對外是公開的則該其他用戶就算沒有配置相關的許可權一樣可以進行相關的操作。當hdfs文件對外許可權是沒有開放的,其他用戶若需要進行相關操作則需要通過Ranger進行相關許可權的配置。 首先 /input賦權 775 許可權 下遞歸賦權750許可權 讓許可權管理交給ranger 測試1 建hive1, ...
  • 對於大數據集群來說,監控功能是非常必要的,通過日誌判斷故障低效,我們需要完整的指標來幫我們管理Kafka集群。本文討論Kafka的監控以及一些常用的第三方監控工具。 一、Kafka Monitoring 首先介紹kafka的監控原理,第三方工具也是通過這些來進行監控的,我們也可以自己去是實現監控,官 ...
  • 距離申請這個博客號已經過了九個月,思前想後還是把知識沉澱放這裡吧,不過初心一樣,依舊是 '謹以此文,見證成果'。有 興趣的話也歡迎大家去我的csdn博客轉一轉。以下是正文: 1.mysql安裝 windows系統下下載 phpstudy(一個集成環境),下載完成後一直按下一步即可,然後 打開phps ...
  • 語法:select 列名, length(列名) from 表名where length(列名) = ( select max(length(列名)) from 表名); 實例:select project_num, length(project_num) from project_infor_ta ...
  • 在mysql查詢中,我們會通過排序,分組等在一張表中讀取數據,這是比較簡單的,但是在真正的應用中經常需要從多個數據表中讀取數據。下麵就為大家介紹這種方式,鏈接查詢join。 INNER JOIN(內連接,或等值連接):獲取兩個表中欄位匹配關係的記錄。 LEFT JOIN(左連接):獲取左表所有記錄, ...
  • 修改表格中的列名稱 alter table \ change [column] \ \ \ 查詢數據表時獲取特定幾行的方式 若需要實現獲取數據表中前幾行或者後幾行的特定內容,需要藉助於limit。 limit子句可以被用於強制select語句返回指定的記錄數。limit 接受一個或兩個數字參數。參數 ...
  • 版權聲明:本文為xing_star原創文章,轉載請註明出處! 本文同步自http://javaexception.com/archives/188 Glide.3x的版本是3.7.0,Glide4.x的版本是4.2.0 Glide3.x中最基礎的用法 那麼在Glide4.x中,其實還是一樣的,最基本 ...
  • 入門學習Flutter有一段時間了,Demo用過的Widget也有不少,想著整體的梳理一下,所以今天結合Flutter中文網和書籍梳理一下Widget的使用,首先梳理一下擁有單個子元素的佈局Widget。 Container:一個擁有繪製、定位、調整大小的Widget Pad... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...