前面咱們對RxHttp作了總體的介紹,咱們知道,使用RxHttp庫發送請求,有兩種方式。一種經過Param+HttpSender的形式,另一種是直接使用RxHttp類,而RxHttp類內部其實就是經過Param+HttpSender實現的,咱們能夠理解爲RxHttp類是Param的代理類。爲此,本文將詳細講解Param類。java
若是還未閱讀前面兩篇文章,請查看git
RxHttp 一條鏈發送請求,新一代Http請求神器(一)github
RxHttp 一條鏈發送請求之強大的數據解析功能(二)json
RxHttp庫已更新至1.0.7版本,詳情請查看RxHttp 源碼數組
首先,附上一張Param類的繼承關係圖,下圖中藍色標註的爲接口類。 網絡
下面將對上圖中的經常使用類及方法作介紹。在前文中,咱們介紹了RxHttp的請求三部曲,以下:app
RxHttp.get("http://...") //第一步,肯定請求方式
.asString() //第二步,肯定返回類型
.subscribe(s -> { //第三部 訂閱觀察者
//成功回調
}, throwable -> {
//失敗回調
});
複製代碼
而其中第一步,內部其實就是操做Param類,在這一步,咱們不只能夠選擇請求方式,還能夠添加參數、添加請求頭、添加文件對象等經常使用的操做,下面詳細講解。異步
首先,咱們來看看Param都給咱們提供了哪些請求方式: ide
上圖爲Param提供的一系列靜態方法,看名字應該也能知道,其中get
方法對應的就是
Get
請求,同理
postXxx
、
putXxx
等方法就是對應的
Post
、
Put
等請求,而考慮到
Post
等請求又能夠有不一樣的形式,故提供了
postForm
、
postJson
方法,其中前者是表單形式,後者是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形式的請求生效,如:postJson
、putJson
、patchJson
、deleteJson
,此方法有兩點須要注意:
注:
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);
}
複製代碼
在上面的Headers
及Headers.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
請求支持文件上傳,其它請求調用此方法,將直接拋出異常;若自定義的請求要支持文件上傳,請重寫此方法。
咱們知道,要拿到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便可,須要特別說明的是getUrl
、getSimpleUrl
方法,其中前者會將參數以Get請求的形式拼接在url後面,並返回;然後者僅返回咱們傳入的url對象。(在RxHttp庫內部,Get、Head請求會調用getUrl方法,其它請求皆調用getSimpleUrl方法)
從上面的結構圖,咱們能夠看到,RxHttp內部提供了10個類,不一樣形式及方式的請求,而後,現實開發中,它並不能知足咱們的業務場景,此時就須要咱們自定義Param。看上圖咱們知道,全部Param的具體實現類,都間接繼承與AbstractParam
類,而對於同一種請求,例如PostFormParam
、PostJsonParam
都繼承於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
轉載請註明出處,謝謝🙏 註解使用請查看