###前言 前面咱们讲了 Okhttp的基本用法 Okhttp3源码解析(1)-OkHttpClient分析android
今天主要分析下Request源码!web
当咱们构建完OkHttpClient对象,须要构造Request对象,构造方式以下:json
final Request request=new Request.Builder()
.url("https://www.wanandroid.com/navi/json")
.get()
.build();
复制代码
拿POST提交表单请求,这时就须要声明一个RequestBody对象了bash
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内部类:socket
而后咱们查一下Request在初始化时配置了哪些参数???ide
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
等字段须要咱们本身去配置:post
请求访问的url ,能够传String与URL 具体方法以下:ui
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()));
}
复制代码
请求类型 String method
,支持多种请求类型this
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.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;
}
复制代码
RequestBody类型,它是抽象类, 有些请求须要咱们传入body实例 ,咱们在经过源码来看一下: 若是是GET请求,body对象传的是null Get与head方法不能传body对象 ,其余method是能够的
若是是POST请求,就须要咱们去设定了
首先咱们看一下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);
}
//省略部分代码...
}
复制代码
核心方法有三个:
今天就讲到这里,但愿对你们有所帮助...
你们能够关注个人微信公众号:「秦子帅」一个有质量、有态度的公众号!