Okhttp3源码解析(2)-Request分析
### 前言
前面我们讲了
[Okhttp的基本用法](https://www.jianshu.com/p/8e404d9c160f)
[Okhttp3源码解析(1)-OkHttpClient分析](https://www.jianshu.com/p/bf1d01b79ce7)
今天主要分析下Request源码!
### Request初始化
当我们构建完OkHttpClient对象,需要构造Request对象,构造方式如下:
###### 1.Get请求
```
final Request request=new Request.Builder()
.url("https://www.wanandroid.com/navi/json")
.get()
.build();
```
###### 2.POST请求
拿POST提交表单请求,这时就需要声明一个RequestBody对象了
```
RequestBody requestBody = new FormBody.Builder()
.add("username", "qinzishuai")
.add("password", "123456")
.build();
Request request = new Request.Builder()
.url("https://www.wanandroid.com/user/login")
.post(requestBody)
.build();
```
看到上面代码是不是很熟悉?和OkHttpClient很相似, 没错 Request 的构建也是Builder模式!

我们点击Request源码进去,果然 其中有静态的Builder内部类:

然后我们查一下**Request在初始化时配置了哪些参数???**
```
public static class Builder {
HttpUrl url;
String method;
Headers.Builder headers;
RequestBody body;
public Builder() {
this.method = "GET";
this.headers = new Headers.Builder();
}
//省略部分代码
public Request build() {
if (url == null) throw new IllegalStateException("url == null");
return new Request(this);
}
}
```
从代码看到了 如果没有声明,默认是Get请求 ` this.method = "GET"` ,至于`url`等字段需要我们自己去配置:
###### HttpUrl
请求访问的url ,可以传String与URL 具体方法如下:
```
public Builder url(String url) {
if (url == null) throw new NullPointerException("url == null");
// Silently replace web socket URLs with HTTP URLs.
if (url.regionMatches(true, 0, "ws:", 0, 3)) {
url = "http:" + url.substring(3);
} else if (url.regionMatches(true, 0, "wss:", 0, 4)) {
url = "https:" + url.substring(4);
}
return url(HttpUrl.get(url));
}
public Builder url(URL url) {
if (url == null) throw new NullPointerException("url == null");
return url(HttpUrl.get(url.toString()));
}
```
###### method
请求类型 `String method `,支持多种请求类型
```
public Builder get() {
return method("GET", null);
}
public Builder head() {
return method("HEAD", null);
}
public Builder post(RequestBody body) {
return method("POST", body);
}
public Builder delete(@Nullable RequestBody body) {
return method("DELETE", body);
}
public Builder delete() {
return delete(Util.EMPTY_REQUEST);
}
public Builder put(RequestBody body) {
return method("PUT", body);
}
public Builder patch(RequestBody body) {
return method("PATCH", body);
}
```
###### Headers
`Headers.Builder ` Http消息的头字段
前面看到了, **我们在初始化Request的时候 同时初始化了headers**, ` this.headers = new Headers.Builder()`
可以通过 `header ` `addHeader ` `removeHeader ` ` headers ` 方法做一些操作
```
public Builder header(String name, String value) {
headers.set(name, value);
return this;
}
public Builder addHeader(String name, String value) {
headers.add(name, value);
return this;
}
public Builder removeHeader(String name) {
headers.removeAll(name);
return this;
}
public Builder headers(Headers headers) {
this.headers = headers.newBuilder();
return this;
}
```
###### body
RequestBody类型,它是抽象类, 有些请求需要我们传入body实例 ,我们在通过源码来看一下:
如果是GET请求,body对象传的是null
**Get与head方法不能传body对象 ,其他method是可以的**

如果是POST请求,就需要我们去设定了

### RequestBody解析
首先我们看一下RequestBody如何初始化??拿提交表单举例:
```
RequestBody requestBody = new FormBody.Builder()
.add("username", "qinzishuai")
.add("password", "000000")
.build();
```
不出所料,也是Builder模式,而且`RequestBody` 是抽象类, `FormBody`是`RequestBody`的其中一种实现类 ,另一个实现类是`MultipartBody`
RequestBody源码如下:
```
public abstract class RequestBody {
/** Returns the Content-Type header for this body. */
public abstract @Nullable MediaType contentType();
/**
* Returns the number of bytes that will be written to {@code sink} in a call to {@link #writeTo},
* or -1 if that count is unknown.
*/
public long contentLength() throws IOException {
return -1;
}
/** Writes the content of this request to {@code sink}. */
public abstract void writeTo(BufferedSink sink) throws IOException;
/**
* Returns a new request body that transmits {@code content}. If {@code contentType} is non-null
* and lacks a charset, this will use UTF-8.
*/
public static RequestBody create(@Nullable MediaType contentType, String content) {
Charset charset = Util.UTF_8;
if (contentType != null) {
charset = contentType.charset();
if (charset == null) {
charset = Util.UTF_8;
contentType = MediaType.parse(contentType + "; charset=utf-8");
}
}
byte[] bytes = content.getBytes(charset);
return create(contentType, bytes);
}
/** Returns a new request body that transmits {@code content}. */
public static RequestBody create(
final @Nullable MediaType contentType, final ByteString content) {
return new RequestBody() {
@Override public @Nullable MediaType contentType() {
return contentType;
}
@Override public long contentLength() throws IOException {
return content.size();
}
@Override public void writeTo(BufferedSink sink) throws IOException {
sink.write(content);
}
};
}
/** Returns a new request body that transmits {@code content}. */
public static RequestBody create(final @Nullable MediaType contentType, final byte[] content) {
return create(contentType, content, 0, content.length);
}
//省略部分代码...
}
```
核心方法有三个:
- contentType()//数据类型
- contentLength()//数据长度
- writeTo(BufferedSink sink) //写操作
今天就讲到这里,希望对大家有所帮助...
大家可以关注我的微信公众号:「秦子帅」一个有质量、有态度的公众号!

Okhttp3源码解析(2)-Request分析的更多相关文章
- Okhttp3源码解析(3)-Call分析(整体流程)
### 前言 前面我们讲了 [Okhttp的基本用法](https://www.jianshu.com/p/8e404d9c160f) [Okhttp3源码解析(1)-OkHttpClient分析]( ...
- Okhttp3源码解析(1)-OkHttpClient分析
### 前言 上篇文章我们讲了[Okhttp的基本用法](https://www.jianshu.com/p/8e404d9c160f),今天根据上节讲到请求流程来分析源码,那么第一步就是实例化OkH ...
- Okhttp3源码解析(4)-拦截器与设计模式
### 前言 回顾: [Okhttp的基本用法](https://www.jianshu.com/p/8e404d9c160f) [Okhttp3源码解析(1)-OkHttpClient分析](htt ...
- Okhttp3源码解析(5)-拦截器RetryAndFollowUpInterceptor
### 前言 回顾: [Okhttp的基本用法](https://www.jianshu.com/p/8e404d9c160f) [Okhttp3源码解析(1)-OkHttpClient分析](htt ...
- 【转】aiohttp 源码解析之 request 的处理过程
[转自 太阳尚远的博客:http://blog.yeqianfeng.me/2016/04/01/python-yield-expression/] 使用过 python 的 aiohttp 第三方库 ...
- lesson8:AtomicInteger源码解析及性能分析
AtomicInteger等对象出现的目的主要是为了解决在多线程环境下变量计数的问题,例如常用的i++,i--操作,它们不是线程安全的,AtomicInteger引入后,就不必在进行i++和i--操作 ...
- Spring源码解析-AOP简单分析
AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等等,不需要去修改业务相关的代码. 对于这部分内容,同样采用一个简单的例子和源码来说明. 接口 public ...
- Okhttp3源码解析
首先是Okhttp的使用: //缓存文件夹 File cacheFile = new File(getExternalCacheDir().toString(), "cache") ...
- Jquery源码解析及案例分析
本人刚学先上链接(别人写的挺好的)后期同步补上
随机推荐
- Excel催化剂开源第35波-图片压缩及自动旋转等处理
Excel催化剂在图片处理方面,也是做到极致化,一般的Excel插件插入图片是原图插入或不可控制压缩比例地方式插入图片至Excel当中,但Excel催化剂的插入图片,是开发了可调节图片大小的插入方式, ...
- 个人永久性免费-Excel催化剂功能第66波-数据快速录入,预定义引用数据逐字提示
在前面好几波的功能中,为数据录入的规范性做了很大的改进,数据录入乃是数据应用之根,没有完整.干净的数据源,再往下游的所有数据应用场景都是空话.在目前IT化进程推进了20多年的现状,是否还仍有必要在Ex ...
- 万能RecyclerView的数据适配器BaseRecyclerViewAdapterHelper
今天楼主才发现github上有这么一个好用的开源代码,充满好奇心的楼主马上使用了,特地分享给大家. 此项目的github地址: https://github.com/CymChad/BaseRecyc ...
- windos10专业版激活(可用)
电脑提示Windows许可证即将到期,于是自己就在网上找了一些教程,但是并没有激活成功,反而由即将到期变为了通知状态,尝试了各种密钥都不行,也下载了激活工具如暴风激活工具,KMS都不管用,尝试了好多方 ...
- iOS 类知乎”分页”效果的实现?
我们先看张gif图看一下效果(LICEcap录制的有点卡, 凑合看) 好像还是卡, 怼个视频演示链接吧: https://m.weibo.cn/1990517135/4398431764047996 ...
- ioc和aop的区别
IoC,(Inverse of Control)控制反转,其包含两个内容:其一是控制,其二是反转.在程序中,被调用类的选择控制权从调用它的类中移除,转交给第三方裁决.这个第三方指的就是Spring的容 ...
- kuberenetes CRD开发指南
扩展kubernetes两个最常用最需要掌握的东西:自定义资源CRD 和 adminsion webhook, 本文教你如何十分钟掌握CRD开发. kubernetes允许用户自定义自己的资源对象,就 ...
- JUint4的下载、配置及对一个算法编写单元测试用例(测试多组数据每组多个参数)
一.JUnit4 jar包下载 链接:https://pan.baidu.com/s/1AdeVGGikcY5dfL151ZnWHA 提取码:h1am 下载完成后,解压一下即可. 二.导入JUnit4 ...
- 【Android】INSTALL_FAILED_UPDATE_INCOMPATIBLE
多是因为已经安装过该 apk 文件了,一般卸载了重新运行就 OK 了.
- Asp.Net Core 发布到 Docker(Linux Centos 虚拟机,使用Dockerfile)
实践一下 Asp.Net Core (基于.net core 2.2)部署到Docker 一.准备工作: 1. 使用Virtualbox创建一个Centos系统的虚拟机,并安装docker和vim 2 ...