HttpSender OkHttp+RxJava超好用、功能超級強大的Http請求框架

不怕天黑發表於2019-01-25

HttpSender

HttpSender 是對OkHttp二次封裝,並與RxJava做到了無縫連線,支援任意Http請求方式,如:Get、Post、Head、Put等;也支援任意資料解析方法,如:Json、DOM解析等;並且可以很優雅的實現上傳/下載進度的監聽。

自問:目前已有Retrofit ,再結合RxJava,傳送請求已經很方便,為啥還要自己去封裝? 自答:Retrofit固然好用,但不是十分的好用,首先,有一定的學習成本;再一個,個人覺得Retrofit在便捷性、程式碼複用性上不是很友好,在看完本篇文章後,或許你會有同感。

本人是一個三流碼農,如有不足之處,理解萬歲!!!!!

HttpSender 開篇之功能使用篇,超好用、功能超級強大的Http請求框架

HttpSender 介紹篇之生命週期、公共引數相關配置

HttpSender 介紹篇之Parser介紹

HttpSender 介紹篇之Param介紹

HttpSender 擴充套件篇之Parser擴充套件

gradle依賴

implementation 'com.http.wrapper:httpsender:1.0.1'
複製程式碼

話不多說,開始,我們拿淘寶獲取IP的介面作為測試介面

ip.taobao.com/service/get…

返回的資料格式如下:

{
    "code": 0,
    "data": { //在這,為了簡單,在data下刪除了部分欄位,只保留3個欄位
        "country": "美國",
        "region": "華盛頓",
        "city": "西雅圖"
    }
}
複製程式碼

對應的Bean類

public class Response {
    private int     code;
    private Address data;
    //省略set、get方法

    class Address {
        private String country; //國家
        private String region; //地區
        private String city; //城市
        //省略set、get方法
    }
}
複製程式碼

傳送Get請求

String url = "http://ip.taobao.com/service/getIpInfo.php";
Param param = Param.get(url) //這裡get,代表Get請求
        .add("ip", "63.223.108.42")//新增引數
        .addHeader("accept", "*/*") //新增請求頭
        .addHeader("connection", "Keep-Alive")
        .addHeader("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
Disposable disposable = HttpSender
        //SimpleParser是一個資料解析器,後續會有介紹,它需要傳入一個泛型,此泛型決定Http的返回型別
        .from(param, new SimpleParser<Response>() {}) //from操作符,是非同步操作
        .observeOn(AndroidSchedulers.mainThread()) //主執行緒回撥
        .subscribe(new Consumer<Response>() {
            @Override
            public void accept(Response response) throws Exception {
                //accept方法引數型別由上面SimpleParser傳入的泛型型別決定
                //走到這裡說明Http請求成功,並且資料正確
            }
        }, new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) throws Exception {
                //Http請求出現異常,有可能是網路異常,資料異常等
            }
        });
複製程式碼

傳送Post請求

String url = "http://ip.taobao.com/service/getIpInfo.php";
Param param = Param.postForm(url) //傳送Form表單形式的Post請求
        .add("ip", "63.223.108.42")//新增引數
        .addHeader("accept", "*/*") //新增請求頭
        .addHeader("connection", "Keep-Alive")
        .addHeader("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
Disposable disposable = HttpSender
        //SimpleParser是一個資料解析器,後續會有介紹,它需要傳入一個泛型,此泛型決定Http的返回型別
        .from(param, new SimpleParser<Response>() {}) //from操作符,是非同步操作
        .observeOn(AndroidSchedulers.mainThread()) //主執行緒回撥
        .subscribe(new Consumer<Response>() {
            @Override
            public void accept(Response response) throws Exception {
                //accept方法引數型別由上面SimpleParser傳入的泛型型別決定
                //走到這裡說明Http請求成功,並且資料正確
            }
        }, new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) throws Exception {
                //Http請求出現異常,有可能是網路異常,資料異常等
            }
        });
複製程式碼

到這你會發現,Get跟Post請求僅僅是獲取Param物件的時候不一樣,即Param.get()和Param.postForm(),後續會對Param詳細介紹。

也許有人會說,傳送一個請求要寫那麼多的程式碼,太麻煩,不好用,我想說的是,以上案例是一個比較完整的請求流程,有帶引數、請求頭,又對返回資料做了自動解析,如果沒有這些,再結合Java 8 的Lambda表示式,你會發現,一切都是那麼的優雅 注:以下程式碼展示均結合Lambda表示式,不懂的同學去了解一下

String url = "http://www.baidu.com";
Disposable disposable = HttpSender
        .fromGet(url) //fromGet非同步操作符,Get請求,內部呼叫了from(Param,Parser)方法
        .observeOn(AndroidSchedulers.mainThread()) //主執行緒回撥
        .subscribe(s -> {
            //Http請求成功
        }, throwable -> {
            //Http請求出現異常
        });
複製程式碼

怎麼樣,是不是很簡單,一條線下來,程式碼簡潔,邏輯清晰 接下來,我們試試檔案上傳,直接上程式碼

String url = "http://www.......";
Param param = Param.postForm(url) //傳送Form表單形式的Post請求
        .add("file1", new File("xxx/1.png"))
        .add("file2", new File("xxx/2.png"))
        .add("key1", "value1")//新增引數,非必須
        .add("key2", "value2")//新增引數,非必須
        .addHeader("versionCode", "100"); //新增請求頭,非必須
Disposable disposable = HttpSender
        .from(param, new SimpleParser<String>() {}) //from操作符,是非同步操作
        .observeOn(AndroidSchedulers.mainThread()) //主執行緒回撥
        .subscribe(s -> { //s為String型別,由SimpleParser類裡面的泛型決定的
            //Http請求成功
        }, throwable -> {
            //Http請求出現異常
        });
複製程式碼

看完你會發現,其實沒什麼,無非就拿到Param物件呼叫add方法傳入檔案,然後呼叫HttpSender傳送出去就ok了。

如果要監聽上傳進度呢?so easy!!!

String url = "http://www.......";
Param param = Param.postForm(url) //傳送Form表單形式的Post請求
        .add("file1", new File("xxx/1.png"))
        .add("file2", new File("xxx/2.png"))
        .add("key1", "value1")//新增引數,非必須
        .add("key2", "value2")//新增引數,非必須
        .addHeader("versionCode", "100"); //新增請求頭,非必須
Disposable disposable = HttpSender
        .upload(param, new SimpleParser<String>() {}) //注:如果需要監聽上傳進度,使用upload操作符
        .observeOn(AndroidSchedulers.mainThread()) //主執行緒回撥
        .doOnNext(progress -> {
            //上傳進度回撥,0-100,僅在進度有更新時才會回撥
            int currentProgress = progress.getProgress(); //當前進度 0-100
            long currentSize = progress.getCurrentSize(); //當前已上傳的位元組大小
            long totalSize = progress.getTotalSize();     //要上傳的總位元組大小
        })
        .filter(Progress::isCompleted)//過濾事件,上傳完成,才繼續往下走
        .map(Progress::getResult) //到這,說明上傳完成,拿到Http返回結果並繼續往下走
        .subscribe(s -> { //s為String型別,由SimpleParser類裡面的泛型決定的
            //上傳成功,處理相關邏輯
        }, throwable -> {
            //上傳失敗,處理相關邏輯
        });
複製程式碼

有上傳,那肯定就有下載,而且還是帶進度回撥的

String url = "http://update.9158.com/miaolive/Miaolive.apk";
//檔案儲存路徑
String destPath = getExternalCacheDir() + "/" + System.currentTimeMillis() + ".apk";
Disposable disposable = HttpSender
        .download(Param.get(url), destPath) //注意這裡使用download操作符
        .observeOn(AndroidSchedulers.mainThread())
        .doOnNext(progress -> {
            //下載進度回撥,0-100,僅在進度有更新時才會回撥
            int currentProgress = progress.getProgress(); //當前進度 0-100
            long currentSize = progress.getCurrentSize(); //當前已下載的位元組大小
            long totalSize = progress.getTotalSize();     //要下載的總位元組大小
        })
        .filter(Progress::isCompleted)//下載完成,才繼續往下走
        .map(Progress::getResult) //到這,說明下載完成,返回下載目標路徑
        .subscribe(s -> {//s為String型別
            //下載完成,處理相關邏輯
        }, throwable -> {
            //下載失敗,處理相關邏輯
        });
複製程式碼

怎麼樣,是不是跟監聽上傳進度的程式碼差不多?這個就是與RxJava結合的好處。

如果我們不想監聽下載進度,更簡單,使用DownloadParser解析器

String url = "http://update.9158.com/miaolive/Miaolive.apk";
//檔案儲存路徑
String destPath = getExternalCacheDir() + "/" + System.currentTimeMillis() + ".apk";
Disposable disposable = HttpSender
        .from(Param.get(url), new DownloadParser(destPath)) //注意這裡使用DownloadParser解析器,並傳入本地路徑
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(s -> {
            //下載成功,處理相關邏輯
        }, throwable -> {
            //下載失敗,處理相關邏輯
        });
複製程式碼

小結: 怎麼樣?看完是不是覺得很簡單,傳送請求三部曲:

  1. 選擇合適的Http請求方式,呼叫Param的get、head、postForm、postJson、putForm等一系列靜態方法建立Param物件,隨後就可新增相關引數資訊,後續會詳細介紹Param
  2. 選擇合適的解析器Parser,目前已經實現了StringParser、SimpleParser、DownloadParser,後面會詳細介紹,可結合自身業務需求擴充套件Parser物件;
  3. 呼叫HttpSender類的fromGet、from、upload、download等操作符傳入Param和Parser物件即可,剩下的就交給RxJava處理了

注:fromGet和download操作符內部也使用了Param和Parser物件,只是做了一層封裝而已

到這你以為就結束了嗎?遠遠沒有,HttpSender更強大的是它的高擴充套件性,例如Param和Parser,後面會寫單獨的文章來介紹

相關文章