Okhttp3源码解析(2)-Request分析
前言
前面我们讲了
Okhttp的基本用法
Okhttp3源码解析(1)-OkHttpClient分析
今天主要分析下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) //写操作
今天就讲到这里,希望对大家有所帮助...
大家可以关注我的微信公众号:「秦子帅」一个有质量、有态度的公众号!
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Block 详解
原文链接:www.imlifengfeng.com 一、概述 闭包 = 一个函数「或指向函数的指针」+ 该函数执行的外部的上下文变量「也就是自由变量」;Block 是 Objective-C 对于闭包的实现。 其中,Block: 可以嵌套定义,定义 Block 方法和定义函数方法相似 Block 可以定义在方法内部或外部 只有调用 Block 时候,才会执行其{}体内的代码 本质是对象,使代码高聚合 使用 clang 将 OC 代码转换为 C++ 文件查看 block 的方法: 在命令行输入代码 clang -rewrite-objc 需要编译的OC文件.m 这时查看当前的文件夹里 多了一个相同的名称的 .cpp 文件,在命令行输入 open main.cpp 查看文件 二、Block的定义与使用 1、无参数无返回值 //1,无参数,无返回值,声明和定义 void(^MyBlockOne)(void) = ^(void){ NSLog(@"无参数,无返回值"); }; MyBlockOne();//block的调用 2、有参数无返回值 //2,有参数,无返回值,声明和定义 void(^...
- 下一篇
30岁以上的程序员该如何自处?
程序员30岁以上,是可以继续技术生涯的. 我身边有很多邻近50+,还在做技术. 如果你喜欢做技术,又能扛得住环境的噪音, 年龄其实不是问题. 遗憾的是,其实很多人并不喜欢软件开发这条技术路, 心里早已存在干几年就要转型的念头, 于是总是容易被外界喧嚣推动的左右摇摆. 假设要继续做技术,想要有持续的职业生命力,这里有2条建议可供参考: 1、大龄程序员选择公司的3大关键点2、保持竞争力的2个建议. 一.大龄程序员选择公司的3个关键点 第一,是关于公司规模的. 大龄开发者尽量不要选择小微创业公司,当然不排除你创业或合伙创业可能性. 原因如下: 1、极其不稳定,一年半载就挂掉的公司占很大比例,会导致你频繁换工作,而且年龄会越来越大,找工作就会越来越难.2、多数小微创业公司,目的是生存,偏向应用类产品. 希望程序员能抗压,加班,一人多用,快速出活,他们并不喜欢大龄开发者. (除非你的技术带头人),因为你的10年开发经验和3年经验在应用项目中干的事情是差不多的.3、技术创新和技术壁垒的构建,需要大把金钱和人力资源,很多小公司压根提供不了这样的环境. 建议: 优先选择中型,大型公司,或者已经在行业内...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- 设置Eclipse缩进为4个空格,增强代码规范
- Mario游戏-低调大师作品
- MySQL8.0.19开启GTID主从同步CentOS8
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS8编译安装MySQL8.0.19
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- SpringBoot2整合Redis,开启缓存,提高访问速度
- CentOS关闭SELinux安全模块