RxHttp 一條鏈發送請求之強大的Param類(三)

簡介

前面咱們對RxHttp作了總體的介紹,咱們知道,使用RxHttp庫發送請求,有兩種方式。一種經過Param+HttpSender的形式,另一種是直接使用RxHttp類,而RxHttp類內部其實就是經過Param+HttpSender實現的,咱們能夠理解爲RxHttp類是Param的代理類。爲此,本文將詳細講解Param類。java

若是還未閱讀前面兩篇文章,請查看git

RxHttp 一條鏈發送請求,新一代Http請求神器(一)github

RxHttp 一條鏈發送請求之強大的數據解析功能(二)json

RxHttp庫已更新至1.0.7版本,詳情請查看RxHttp 源碼數組

Param結構

首先,附上一張Param類的繼承關係圖,下圖中藍色標註的爲接口類。 網絡

在這裏插入圖片描述
下面將對上圖中的經常使用類及方法作介紹。

Param介紹

在前文中,咱們介紹了RxHttp的請求三部曲,以下:app

RxHttp.get("http://...")              //第一步,肯定請求方式
        .asString()                     //第二步,肯定返回類型
        .subscribe(s -> {               //第三部 訂閱觀察者
            //成功回調
        }, throwable -> {
            //失敗回調
        });
複製代碼

而其中第一步,內部其實就是操做Param類,在這一步,咱們不只能夠選擇請求方式,還能夠添加參數、添加請求頭、添加文件對象等經常使用的操做,下面詳細講解。異步

請求方式

首先,咱們來看看Param都給咱們提供了哪些請求方式: ide

在這裏插入圖片描述
上圖爲Param提供的一系列靜態方法,看名字應該也能知道,其中 get方法對應的就是 Get請求,同理 postXxxputXxx等方法就是對應的 PostPut等請求,而考慮到 Post等請求又能夠有不一樣的形式,故提供了 postFormpostJson方法,其中前者是表單形式,後者是Json形式。現實開發中,若是還有其它的形式的請求(如:發送加密的請求),就須要咱們自定義Param類,以知足咱們的業務需求,後續會講解。

如今咱們來看看Param是怎麼定義的:post

public interface Param extends ParamBuilder, HeadersBuilder, NoBodyRequest, RequestBuilder {

    //Get請求
    static Param get(@NonNull String url) {
        return GetParam.with(url);
    }
    //Post請求,參數以Form表單鍵值對的形式提交
    static Param postForm(@NonNull String url) {
        return PostFormParam.with(url);
    }

    //省略其它方法
}
複製代碼

能夠看到Param就是一個接口,而且繼承了ParamBuilder、HeadersBuilder、NoBodyRequest、RequestBuilder這四個接口

添加請求參數

肯定了請求方式後,咱們就須要添加請求參數,RxHttp提供了3個方法:

//對參數的操做都在此接口裏
public interface ParamBuilder {
    //添加單個參數
    Param add(String key, Object value);

    //經過map添加多個參數
    Param add(Map<? extends String, ?> map);

    //設置json字符串參數,調用此方法後,經過上面兩個add方法添加的參數將失效;非Json請求調用此方法無任何做用
    Param setJsonParams(String jsonParams);
    
   //省略若干方法
}
複製代碼

第一個是添加單個參數,其中value是Object類型,故咱們能夠添加任意類型的參數,而不用進行強轉(這一點對於強迫症患者的我,真的很實用);第二個是經過map對象添加多個參數;第三個方法setJsonParams僅對Json形式的請求生效,如:postJsonputJsonpatchJsondeleteJson,此方法有兩點須要注意:

  • 非Json形式的請求調用此方法將不會產生任何做用
  • Json形式的請求調用此方法後,不論是以前仍是後面經過add方法添加的參數都將失效

注:Param 內部是經過LinkedHashMap存儲參數。

添加請求頭

對請求頭的操做,都封裝在一個接口裏,代碼以下:

public interface HeadersBuilder {

    Headers getHeaders();

    String getHeader(String key);

    Headers.Builder getHeadersBuilder();

    Param setHeadersBuilder(Headers.Builder builder);

    Param addHeader(String key, String value);

    Param addHeader(String line);

    Param setHeader(String key, String value);

    Param removeAllHeader(String key);
}
複製代碼

在上面的HeadersHeaders.Builder都是OkHttp內部提供的類,故能夠知道在Param內部是經過Headers.Builder存儲的請求頭信息。

添加文件

Param內部目前僅提供了一個添加文件的方法,以下:

//對參數的操做都在此接口裏
public interface ParamBuilder {
    /** * <p>添加文件對象 * <P>默認不支持,若有須要,自行擴展,參考{@link PostFormParam} * * @param key 鍵 * @param file 文件對象 * @return Param */
    default Param add(String key, File file) {
        throw new UnsupportedOperationException("Please override if you need");
    }
   
    //省略若干方法
}
複製代碼

能夠看到,此方法默認會拋出一個UnsupportedOperationException異常,即表明不支持這個操做,若是要支持,須要重寫此方法。目前RxHttp內部僅有postForm請求重寫了此方法,故僅有postForm請求支持文件上傳,其它請求調用此方法,將直接拋出異常;若自定義的請求要支持文件上傳,請重寫此方法。

從新設置Url

咱們知道,要拿到Param對象就必須調用相關靜態方法,並傳入url。而後現實開發中,咱們可能須要動態更改url,又或者咱們須要拿到當前url作一些判斷,爲此RxHttp提供了相關方法,咱們來看看

public interface ParamBuilder {

    Param setUrl(@NonNull String url);
}
複製代碼
public interface NoBodyRequest {
    /** * @return 帶參數的url */
    String getUrl();
    /** * @return 不帶參數的url */
    String getSimpleUrl();
    
    //省略相關方法
}
複製代碼

setUrl好理解,傳入一個url便可,須要特別說明的是getUrlgetSimpleUrl方法,其中前者會將參數以Get請求的形式拼接在url後面,並返回;然後者僅返回咱們傳入的url對象。(在RxHttp庫內部,Get、Head請求會調用getUrl方法,其它請求皆調用getSimpleUrl方法)

自定義Param

從上面的結構圖,咱們能夠看到,RxHttp內部提供了10個類,不一樣形式及方式的請求,而後,現實開發中,它並不能知足咱們的業務場景,此時就須要咱們自定義Param。看上圖咱們知道,全部Param的具體實現類,都間接繼承與AbstractParam類,而對於同一種請求,例如PostFormParamPostJsonParam都繼承於AbstractPostParam。所以,咱們要自定義Param,能夠繼承AbstractXxxParam類便可。 例如,咱們如今要實現一個Post請求,參數以加密後的Json字符串發出,代碼就能夠這些寫

public class PostEncryptJsonParam extends AbstractPostParam {

    public PostEncryptJsonParam(String url) {
        super(url);
    }

    /** * @return 根據本身的業務需求返回對應的RequestBody */
    @Override
    public RequestBody getRequestBody() {
        return null;
    }
}
複製代碼

能夠看到,咱們只須要實現一個getRequestBody()方法,並返回一個RequestBody對象便可,咱們再來看看實現

@Param(methodName = "postEncryptJson")
public class PostEncryptJsonParam extends AbstractPostParam {

    private static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json;charset=utf-8");

    public PostEncryptJsonParam(String url) {
        super(url);
    }

    /** * @return 根據本身的業務需求返回對應的RequestBody */
    @Override
    public RequestBody getRequestBody() {
        //咱們要發送Post請求,參數以加密後的json形式發出
        //第一步,將參數轉換爲Json字符串
        JsonObject jsonObject = BuildUtil.mapToJson(this);
        String json = jsonObject.toString();
        //第二步,加密
        byte[] encryptByte = encrypt(json, "RxHttp");
        //第三部,建立RequestBody並返回
        RequestBody requestBody = RequestBody.create(MEDIA_TYPE_JSON, encryptByte);
        return requestBody;
    }

    /** * @param content 要加密的字符串 * @param password 密碼 * @return 加密後的字節數組 */
    private byte[] encrypt(String content, String password) {
        //加密代碼省略
        return null;
    }
}
複製代碼

能夠看到,很是簡單,首先將參數轉換爲Json字符串,而後進行加密,最後根據加密後的數據建立RequestBody對象並返回便可,如今咱們來看看如何使用PostEncryptJsonParam這個類。

注:咱們在PostEncryptJsonParam類上使用了註解@Param(methodName = "postEncryptJson"),Rebuild一下項目,就會在RxHttp類下生成一個static RxHttp postEncryptJson(String url)的靜態方法。 關於註解的使用,請查看RxHttp 擴展篇之註解處理器 Generated API(八) 此時咱們就能夠這麼作

String url = "http://www....";
  RxHttp.postEncryptJson(url)  //postEncryptJson 是使用註解生成的方法
        .add("key1", "value1")
        .add("key2", "value3")//添加參數
        .asData(Address.class) //asXXX操做符,是異步操做
        .as(RxLife.asOnMain(this)) //感知生命週期,並在主線程回調
        .subscribe(address -> {
            //accept方法參數類型由上面DataParser傳入的泛型類型決定
            //走到這裏說明Http請求成功,而且數據正確
        }, throwable -> {
            //Http請求出現異常,有多是網絡異常,數據異常等
        });
複製代碼

能夠看到,使用RxHttp.postEncryptJson(url)靜態方法獲得PostEncryptJsonParam對象,並添加相關參數便可,其它邏輯沒有任何改變。

到這,我能夠告訴你,AbstractPostParam、AbstractPutParam、AbstractPatchParam、AbstractDeleteParam這4個抽象類,實際上是同樣的邏輯,都只須要實現getRequestBody()方法便可。

小結

到這,你會發現,Param在RxHttp庫中是一個很是重要的角色,它提供了很是多簡單易用的Api,這使得RxHttp很是的好用。

最後,本文若是有寫的不對的地方,請廣大讀者指出。 若是以爲我寫的不錯,記得給我點贊RxHttp

轉載請註明出處,謝謝🙏 註解使用請查看

RxHttp 一條鏈發送請求之註解處理器 Generated API(四)

相關文章
相關標籤/搜索