当前位置: 移动技术网 > IT编程>移动开发>Android > Okhttp3源码解析(2)-Request分析

Okhttp3源码解析(2)-Request分析

2019年08月23日  | 移动技术网IT编程  | 我要评论

索毛毛,飘逸之旅,我的豪门爱人

### 前言 前面我们讲了 [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模式! ![](https://img2018.cnblogs.com/blog/1312938/201908/1312938-20190823180241877-899976016.png) 我们点击request源码进去,果然 其中有静态的builder内部类: ![](https://img2018.cnblogs.com/blog/1312938/201908/1312938-20190823180242273-1916386988.png) 然后我们查一下**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是可以的** ![](https://img2018.cnblogs.com/blog/1312938/201908/1312938-20190823180242513-433063641.png) 如果是post请求,就需要我们去设定了 ![](https://img2018.cnblogs.com/blog/1312938/201908/1312938-20190823180242695-600270897.png) ### 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) //写操作 今天就讲到这里,希望对大家有所帮助... 大家可以关注我的微信公众号:「秦子帅」一个有质量、有态度的公众号! ![公众号](https://img2018.cnblogs.com/blog/1312938/201908/1312938-20190823180242882-2108811045.jpg)

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网