博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
RxHttp 一条链发送请求之强大的Param类(三)
阅读量:7208 次
发布时间:2019-06-29

本文共 6065 字,大约阅读时间需要 20 分钟。

简介

前面我们对RxHttp做了整体的介绍,我们知道,使用RxHttp库发送请求,有两种方式。一种通过Param+HttpSender的形式,另外一种是直接使用RxHttp类,而RxHttp类内部其实就是通过Param+HttpSender实现的,我们可以理解为RxHttp类是Param的代理类。为此,本文将详细讲解Param类。

如果还未阅读前面两篇文章,请查看

RxHttp库已更新至1.0.7版本,详情请查看

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 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
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 {    /**     * 

添加文件对象 *

默认不支持,如有需要,自行扩展,参考{

@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)的静态方法。 关于注解的使用,请查看 此时我们就可以这么做

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非常的好用。

最后,本文如果有写的不对的地方,请广大读者指出。 如果觉得我写的不错,记得给我点赞

转载请注明出处,谢谢? 注解使用请查看

转载于:https://juejin.im/post/5cc47e575188252da72219ca

你可能感兴趣的文章
在WPF中使用WinForm控件方法
查看>>
Linux Kernel 3.0.50/3.2.33/3.4.17/3.6.5
查看>>
在Oracle中查询存储过程和函数
查看>>
关于对象序列化json 说说
查看>>
设置div滚动条
查看>>
git常用命令
查看>>
邁向IT專家成功之路的三十則鐵律 鐵律十三:IT人理財之道-知足
查看>>
SpringMVC请求处理流程
查看>>
路由器发展编年史 完结篇
查看>>
餐馆个性化推荐应用
查看>>
Spring+Struts+Hibernate 简介(转)
查看>>
微服务架构优缺点
查看>>
史上最快、最强大的 Gradle 5.0 发布,新特性全解!
查看>>
开发要不要自己做测试?怎么做?
查看>>
10亿次机器翻译,2018天猫双11大量启用AI员工
查看>>
小米6的“小问题” 其实是小米的大麻烦
查看>>
联想AI战略凶猛推进 多设备,跨平台精准实现智能生活
查看>>
乐视网称贾跃亭旗下资产世茂工三拍卖与上市公司无关
查看>>
专访网秦创始人林宇:我曾每天戴20公斤手铐 生不如死
查看>>
英国内政部启动遣返程序 数百非法入境者或遭驱逐
查看>>