RxHttp基本功能介绍的时候,我们看到,通过RxHttp,我们可以确定请求方式,及调用一系列addXXX
方法去添加参数、头部、文件等信息,其实在内部就是在操作Param类,Param为我们提供类一静态方法,供我们选择具体的请求方式。
如果还未看过之前的文章,请移步
RxHttp 一条链发送请求,新一代Http请求神器(一)
RxHttp 介绍篇之生命周期、公共参数相关配置(二)
RxHttp 介绍篇之Parser介绍(三)
RxHttp 介绍篇之Param介绍(四)
RxHttp 介绍篇之多请求串行与并行(五)
RxHttp 扩展篇之Parser扩展(六)
RxHttp 扩展篇之Param扩展(七)
RxHttp 扩展篇之注解处理器 Generated API(八)
首先,我们来看看Param的源码
可以看到Param就是一个接口类,继承了ParamBuilder, HeadersBuilder, NoBodyRequest, RequestBuilder这个4个接口类,并提供一系列静态方法来获取Param对象,我们先来介绍Param继承的4个接口类。
首先ParamBuilder接口,看名字应该能知道,里面提供的应该是添加参数的方法
public interface ParamBuilder {
Param setUrl(@NonNull String url);
Param add(String key, Object value);
/**
* <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");
}
/**
* <p>设置上传进度监听器
* <p>默认不支持,如有需要,自行扩展,参考{@link PostFormParam}
*
* @param callback 进度回调对象
* @return Param
*/
default Param setProgressCallback(ProgressCallback callback) {
throw new UnsupportedOperationException("Please override if you need");
}
}
果然,里面提供类add方法及两个set方法,接着,我们看看HeadersBuilder接口
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);
}
里面提供了一系列与请求头相关的方法,再来看看NoBodyRequest接口
public interface NoBodyRequest {
/**
* @return 带参数的url
*/
String getUrl();
/**
* @return 不带参数的url
*/
String getSimpleUrl();
/**
* @return 请求头信息
*/
Headers getHeaders();
/**
* @return tag
*/
Object getTag();
/**
* @return 缓存控制器
*/
CacheControl getCacheControl();
}
NoBodyRequest里面提供的方法,用于构建一个Request对象。
最后看看RequestBuilder
public interface RequestBuilder {
/**
* @return 构建一个请求
*/
Request buildRequest();
}
里面就一个构建Request对象的方法,其实NoBodyRequest接口与RequestBuilder接口是对应的,通过NoBodyRequest接口的方法拿到构建Request的相关参数,然后通过RequestBuilder去构建一个Request,这里面接口比较多,可能需要读者慢慢品味。
Param继承的接口介绍了,那么Param都有哪些具体实现类呢?看Param类里面的with方法,我们知道,共有10个具体实现类,例如:GetParam、HeadParam、PostFormParam、PostJsonParam等用于发送不同方式请求的Param实现类。
我们先来看看GetParam类
public final class GetParam extends AbstractParam implements GetRequest {
private GetParam(@NonNull String url) {
super(url);
}
static GetParam with(String url) {
return new GetParam(url);
}
@Override
public Request buildRequest() {
return BuildUtil.buildGetRequest(this);
}
}
GetParam继承AbstractParam并实现了GetRequest接口,先看看GetRequest是什么鬼?
public interface GetRequest extends NoBodyRequest {
}
可以看到GetRequest继承NoBodyRequest接口,并且自己没有任何方法,我想这里你就会明白为啥叫NoBodyRequest,因为Get请求没有请求体(RequestBody)。
接着,我们看看AbstractParam,看名字我们知道,它是一个Param的抽象实现类
public abstract class AbstractParam extends LinkedHashMap<String, String> implements Param {
private String mUrl; //链接地址
private Builder mHBuilder; //请求头构造器
public AbstractParam(@NonNull String url) {
this.mUrl = url;
}
/**
* @return 带参数的url
*/
@Override
public final String getUrl() {
return BuildUtil.mergeUrlAndParams(mUrl, this);
}
public AbstractParam setUrl(@NonNull String url) {
mUrl = url;
return this;
}
/**
* @return 不带参数的url
*/
@Override
public final String getSimpleUrl() {
return mUrl;
}
@Nullable
@Override
public final Headers getHeaders() {
return mHBuilder == null ? null : mHBuilder.build();
}
@Override
public final Builder getHeadersBuilder() {
if (mHBuilder == null)
mHBuilder = new Builder();
return mHBuilder;
}
@Override
public Param setHeadersBuilder(Builder builder) {
mHBuilder = builder;
return this;
}
@Override
public final Param addHeader(String key, String value) {
getHeadersBuilder().add(key, value);
return this;
}
@Override
public final Param addHeader(String line) {
getHeadersBuilder().add(line);
return this;
}
@Override
public final Param setHeader(String key, String value) {
getHeadersBuilder().set(key, value);
return this;
}
@Override
public final String getHeader(String key) {
return getHeadersBuilder().get(key);
}
@Override
public final Param removeAllHeader(String key) {
getHeadersBuilder().removeAll(key);
return this;
}
@Override
public final Param add(String key, String value) {
super.put(key, value);
return this;
}
@Override
public CacheControl getCacheControl() {
return null;
}
@Override
public Object getTag() {
return null;
}
/**
* @return 所有参数(不包括url及请求头)以 key=value 格式拼接(用 & 拼接)在一起
*/
@Override
public final String toString() {
return BuildUtil.toKeyValue(this);
}
}
AbstractParam是一个非常重要的类,所有Param的具体实现类,都直接或者简直继承AbstractParam,可以看到,它继承了LinkedHashMap,并有两个全局变量mUrl即mHBuilder(请求头构造器),那么我们就知道了AbstractParam承载了url、请求参数、请求头的相关逻辑,因此所有的Param实现类都直接或者简直继承了它。
接着,我们来看看PostFormParam的具体实现
public class PostFormParam extends AbstractPostParam implements ProgressParam {
private ProgressCallback mCallback; //上传进度回调
private LinkedHashMap<String, File> mFileMap; //附件集合
private PostFormParam(@NonNull String url) {
super(url);
}
static PostFormParam with(String url) {
return new PostFormParam(url);
}
/**
* 设置上传进度监听器
* @param callback 进度回调对象
* @return PostFormParam
*/
@Override
public final PostFormParam setProgressCallback(ProgressCallback callback) {
mCallback = callback;
return this;
}
@Override
public RequestBody getRequestBody() {
RequestBody requestBody = hasFile() ? BuildUtil.buildFormRequestBody(this, mFileMap)
: BuildUtil.buildFormRequestBody(this);
final ProgressCallback callback = mCallback;
if (callback != null) {
//如果设置了进度回调,则对RequestBody进行装饰
return new ProgressRequestBody(requestBody, callback);
}
return requestBody;
}
@Override
public final PostFormParam add(String key, File file) {
Map<String, File> fileMap = mFileMap;
if (fileMap == null)
fileMap = mFileMap = new LinkedHashMap<>();
fileMap.put(key, file);
return this;
}
private boolean hasFile() {
final Map fileMap = mFileMap;
return fileMap != null && fileMap.size() > 0;
}
}
PostFormParam继承AbstractPostParam,并实现了ProgressParam接口,ProgressParam是一个设置上传进度监听器的接口,这里不做过多介绍,我们再来看看AbstractPostParam是什么鬼
/**
* Post请求继承本类
* User: ljx
* Date: 2019/1/19
* Time: 11:36
*/
public abstract class AbstractPostParam extends AbstractParam implements PostRequest {
public AbstractPostParam(@NonNull String url) {
super(url);
}
@Override
public final Request buildRequest() {
return BuildUtil.buildPostRequest(this);
}
}
到这,我们明白,所有发送Post请求的Param都应该继承AbstractPostParam,它有两个实现类分别是:PostFormParam和PostJsonParam。
我们继续回到PostFormParam,它里面有两个全局变量,分别是mCallback和mFileMap,一个是上传进度监听器,一个是要上传的附件集合,通过这两个变量及请求参数共同构建一个RequestBody,然后AbstractPostParam实现RequestBuilder接口里的方法,构建一个Request。
总结
看完GetPara和PostFormParam的介绍,我们会发现,Param具体实现类,最终目的就是为了实现RequestBuilder接口构建一个Request,而构建Request又需要Url、RequestBody、Header等一系列参数,所以就有NoBodyRequest接口,当然也有BodyRequest接口(用户构建一个请求体),通过一系列接口的组拼与实现,最终造就了Param接口的强大。