簡介
前面我們對RxHttp做了整體的介紹,我們知道,使用RxHttp庫傳送請求,有兩種方式。一種通過Param+HttpSender的形式,另外一種是直接使用RxHttp類,而RxHttp類內部其實就是通過Param+HttpSender實現的,我們可以理解為RxHttp類是Param的代理類。為此,本文將詳細講解Param類。
如果還未閱讀前面兩篇文章,請檢視
Param結構
首先,附上一張Param類的繼承關係圖,下圖中藍色標註的為介面類。
下面將對上圖中的常用類及方法做介紹。Param介紹
在前文中,我們介紹了RxHttp的請求三部曲,如下:
RxHttp.get("http://...") //第一步,確定請求方式
.asString() //第二步,確定返回型別
.subscribe(s -> { //第三部 訂閱觀察者
//成功回撥
}, throwable -> {
//失敗回撥
});
複製程式碼
而其中第一步,內部其實就是操作Param類,在這一步,我們不僅可以選擇請求方式,還可以新增引數、新增請求頭、新增檔案物件等常用的操作,下面詳細講解。
請求方式
首先,我們來看看Param都給我們提供了哪些請求方式:
上圖為Param提供的一系列靜態方法,看名字應該也能知道,其中get
方法對應的就是Get
請求,同理postXxx
、putXxx
等方法就是對應的Post
、Put
等請求,而考慮到Post
等請求又可以有不同的形式,故提供了postForm
、postJson
方法,其中前者是表單形式,後者是Json形式。現實開發中,如果還有其它的形式的請求(如:傳送加密的請求),就需要我們自定義Param類,以滿足我們的業務需求,後續會講解。
現在我們來看看Param是怎麼定義的:
public interface Param extends IParam, IHeaders, IRequest {
//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 IParam {
//新增單個引數
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
,此方法有兩點需要注意:
- 非Json形式的請求呼叫此方法將不會產生任何作用
- Json形式的請求呼叫此方法後,不管是之前還是後面通過add方法新增的引數都將失效
注:
Param 內部是通過LinkedHashMap儲存引數。
新增請求頭
對請求頭的操作,都封裝在一個介面裡,程式碼如下:
public interface IHeaders {
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 IParam {
/**
* <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 IParam {
Param setUrl(@NonNull String url);
}
複製程式碼
public interface IRequest {
/**
* @return 帶引數的url
*/
String getUrl();
/**
* @return 不帶引數的url
*/
String getSimpleUrl();
//省略相關方法
}
複製程式碼
setUrl
好理解,傳入一個url即可,需要特別說明的是getUrl
、getSimpleUrl
方法,其中前者會將引數以Get請求的形式拼接在url後面,並返回;而後者僅返回我們傳入的url物件。(在RxHttp庫內部,Get、Head請求會呼叫getUrl方法,其它請求皆呼叫getSimpleUrl方法)
自定義Param
從上面的結構圖,我們可以看到,RxHttp內部提供了4個類,不同形式及方式的請求,然後,現實開發中,它並不能滿足我們的業務場景,此時就需要我們自定義Param。看上圖我們知道,所有Param的具體實現類,都直接繼承與AbstractParam
類,因此,我們要自定義Param,可以繼承AbstractParam類,當前也可根據自己的提交方式,直接繼承NoBodyParam、FormParam、JsonParam等。
例如,我們現在要傳送Post請求,引數已Json字串的形式提交,並且引數需要加密,那我們就可以直接繼承JsonParam類,如下:
public class PostEncryptJsonParam extends JsonParam {
public PostEncryptJsonParam(String url) {
super(url, Method.POST);
}
/**
* @return 根據自己的業務需求返回對應的RequestBody
*/
@Override
public RequestBody getRequestBody() {
return null;
}
}
複製程式碼
可以看到,我們只需要實現一個getRequestBody()方法,並返回一個RequestBody物件即可,我們再來看看實現
@Param(methodName = "postEncryptJson")
public class PostEncryptJsonParam extends JsonParam {
private static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json; charset=utf-8");
public PostEncryptJsonParam(String url) {
super(url, Method.POST);
}
/**
* @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")//新增引數
.asResponse(Address.class) //asXXX操作符,是非同步操作
.as(RxLife.asOnMain(this)) //感知生命週期,並在主執行緒回撥
.subscribe(address -> {
//accept方法引數型別由上面DataParser傳入的泛型型別決定
//走到這裡說明Http請求成功,並且資料正確
}, throwable -> {
//Http請求出現異常,有可能是網路異常,資料異常等
});
複製程式碼
可以看到,使用RxHttp.postEncryptJson(url)
靜態方法得到PostEncryptJsonParam物件,並新增相關引數即可,其它邏輯沒有任何改變。
小結
到這,你會發現,Param在RxHttp庫中是一個非常重要的角色,它提供了非常多簡單易用的Api,這使得RxHttp非常的好用。
最後,本文如果有寫的不對的地方,請廣大讀者指出。 如果覺得我寫的不錯,記得給我點贊RxHttp
轉載請註明出處,謝謝? 註解使用請檢視