OkHttp3源码(四) ------ RequestBody

接下来是对RequestBody抽象类的分析,因为内部实现很简单,所以这里贴出加注释的源码,供大家阅读。对于RequestBody抽象类,我们只需要细看最后两个有具体实现的方法。

RequestBody类主要做了获得请求体的数据类型获得请求体的数据长度将请求体写入到流中这三件事。

我们看一下它的源码。

1、两个抽象方法

//获取请求体的类型
public abstract MediaType contentType();
//将请求正文写到指定的输出流中
public abstract void writeTo(BufferedSink sink) throws IOException;

因为正文内容的类型是由用户定义的,所以这里将它写成抽象的,又因为正文内容的类型不同,影响到将正文写到指定输出流的具体实现,所以将writeTo(……)写成抽象,让用户自己实现。

2、获取请求正文的内容长度

//获取请求体的数据长度
public long contentLength() throws IOException {
return -1;
}

这个方法没有写成抽象,是因为它的具体实现不会影响到RequestBody能不能用,但是一般这个方法都会在子类中复写。

3、实例化RequestBody抽象类

//创建指定类型的请求正文,类型的选择需要根据想要上传的数据而定的。
public static RequestBody create(MediaType contentType, String content) {
}
public static RequestBody create(final MediaType contentType, final byte[] content) {
}

//上面两个方法最终会调用这个放方法
public static RequestBody create(final MediaType contentType, final byte[] content,
final int offset, final int byteCount) {
if (content == null) throw new NullPointerException("content == null");
Util.checkOffsetAndCount(content.length, offset, byteCount);
return new RequestBody() {
@Override public MediaType contentType() {
return contentType; //字节数组数据的类型
}

@Override public long contentLength() {
return byteCount; //字节数组的长度
}

@Override public void writeTo(BufferedSink sink) throws IOException {
sink.write(content, offset, byteCount); //将字节数组写入流中
}
};
}

//一般实现上传文件的时候调用
public static RequestBody create(final MediaType contentType, final File file) {
if (file == null) throw new NullPointerException("content == null");

return new RequestBody() {
@Override public MediaType contentType() {
return contentType; //文件的类型
}

@Override public long contentLength() {
return file.length(); //获得文件的大小
}

@Override public void writeTo(BufferedSink sink) throws IOException {
Source source = null;
try {
source = Okio.source(file); //获得指定文件的读取流
sink.writeAll(source);  //写入文件的读取流
} finally {
Util.closeQuietly(source);
}
}
};

通过上面的方法我们可以创建出我们想要的任何类型的请求正文。

4、RequestBody的两个子类

FormBody(表单)类:
用于实现一般键值(都是字符串类型)对的上传
主要通过两个List集合来存储动态增加的键和值,最后一次性写入输入流的缓存区。
MultipartBody(多部分类):
1、提到“部分”,要说Http的“多部分上传”,每一“部分”都包含请求头(可有可无)和请求体“部分”可以看作是一个简略版的小报文(小请求),只不过这里的报文首部字段只能用实体首部字段
2、“部分”这一概念通过MultipartBody类的内部类Part来具体实现。
3、通过集合的方式存储动态添加的“部分”。

关于首部字段不太明白的朋友,请参见Http首部的字段及相应的取值内容

学习心得:观看资料 + 思考问题 + 实践证明 + 总结概括 + 整理记录 = 有思想的技术大牛。

你可能感兴趣的:(android,框架)