okhttp各种请求报文你真的懂吗?

Okhttp每天都在用,请求每天都在发,但是客户端用okhttp构建的每一个请求,你知道他的请求报文是什么样的吗?什么是表单提交?什么是媒体提交?表单提交和媒体提交的请求报文有什么不一样的吗?上传文件的请求的报文又是什么样的?如果上传文件的同时又要求携带参数,这时报文是什么样的?其实我们每天都在处理着这些东西,只不过很少有人注意各种各样的请求的背后到底有什么不同。本文将使用Okhttp完成各种平时常见的请求,并对比不同请求的报文,通过这些相信对okhttp会有一个更深的理解。

1.请求报文

在这里插入图片描述
http的请求报文格式是固定的,从上往下分为四部分:
第一部分:也就是第一行,请求行,包含请求方法(get或post等)、url、协议
第二部分:请求所携带的一系列Header参数,从第二行开始一行行的向下罗列,每一个header参数占一行,直到遇到一行只有回车符的位置结束
第三部分:只有一个回车符,将header部分与body部分分隔
第四部分:body

2.表单提交

表单提交在安卓的世界里好像并不是很常见,它通常在网页有更多的应用。用okhttp来提交一个表单:

在这里插入图片描述
FormBody是okhttp提供的类继承自RequestBody。代码很简单向www.baidu.com提交了一个name为tom的表单,这个表单请求的报文是这样的:

在这里插入图片描述
表单提交的时候,header中的 Content-Type: application/x-www-form-urlencoded 告诉服务器,我body中的数据格式是表单格式的,你需要按照表单的格式接收处理。可以看到此时body的内容就是: name=tom 这样的一个字符串。

3. json提交

json提交在安卓中可能是用的最多的方法,他把要提交的数据转化成json格式传给服务器,服务器也按照json的格式进行解析

在这里插入图片描述

代码中我们直接定义了一个json格式的字符串做为body提交,代码很简单直接看对应的请求报文:

在这里插入图片描述
在json提交中,header中的 Content-Type: application/json; charset=utf-8 告诉服务器我的body是采用的json格式的,你需要按照json的格式接收处理。可以看到此时body的内容就是: {“username”: “lisi”, “nickname” : “李四”} 这样的一个标准的json格式字符串。

4.文件提交

通常我们会遇到上传头像、上传音乐这种将整个文件上传给服务器的需求。那上传文件和上边两个表单提交、json提交有什么区别吗?答案是:完全没有。文件的本质也是一堆数据,所以上传文件就是把文件这一堆数据读进来,在放到请求中提交出去!只不过文件有可能很大,为了传输大家做了很多的优化比如分段上传。

在这里插入图片描述
在我手机的sdcard的根目录我创建了一个文件 1.txt 的文本文件,这个文本文件中只写了一句 hello 的文案。再看对应的报文:

在这里插入图片描述
在文件提交中,header中的 Content-Type: File/* 告诉服务器我的body是一个文件。可以看到 1.txt文本文件的内容被直接读取放到了请求的body中。 所以文件上传和普通的接口请求相比并没有什么特殊的地方,只不过是把文件中的内容当做body来直接提交。当然这是最简单的情况,如果文件较大,还需要做分包上传等其他的优化。

4.带参数的文件上传

如果我想在上传文件的同时在携带一些参数来描述该文件的一些属性,这个当然也是支持的:

在这里插入图片描述
此时由于是文件内容参数同时混合在body中,为了服务器能够区分出body中不同的数据,所以肯定需要一种规则来排放文件内容参数,此时的报文是这样的:

在这里插入图片描述
在文件和参数混合提交中,header中的 Content-Type: multipart/mixed;告诉服务器我的body是一个文件和参数混合的格式。
boundary=dac9cf94-d511-428e-b9d0-cc1a4152cde1 表示body中文件和参数混合的数据使用 dac9cf94-d511-428e-b9d0-cc1a4152cde1 字符串进行了分隔,这样服务器就可以根据这些信息区分出body不同的数据了。

总结

okhttp中的RequestBody是一个抽象类,含有writeTo 抽象方法,http报文中的body部分就是 writeTo方法输出的内容。
1、MultipartBody:内部含有一个Part的列表。Part类内部持有一个Header和一个RequestBody。所以MultipartBody的 writeTo方法就是遍历Part列表,把所有的RequestBody都输出。按照boundary分隔的格式输出
2、FormBody:只能传递键值对。内部持有键的列表和值的列表,writeTo方法就是遍历列表把键值对拼接,按照键值对的格式输出
3、RequestBody.create 方法:直接创建一个RequestBody的匿名类,将内容直接输出,没有格式。create方法中传的是什么,最终Http报文中的body就是什么。
看到这应该对于使用okhttp发不同请求携带各种样式的参数有了一个更直观的认识了,以后再跟后端同学定接口撕逼的时候腰杆要直直的!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值