朋友圈上传图片+文字怎么破?
来源:互联网 发布:中科汇联 cms 编辑:程序博客网 时间:2024/04/28 04:36
需求
Retrofit普及后,最近好多人都在问,如何实现Retrofit上传多文件+文字需求(朋友圈发图片+文字)
解决方案
google: retrofit upload multiple files
说重点
与其直接说答案,不如我们花点时间说说多文件上传的原理,这样,以后就算出了其他的http框架,你也能快速实现。
HTTP协议就不讲了吧?反正copy一段过来也不会有人看。我们就直接跳到文件上传去。想看也可以,传送门
post form 表单
上图是不是很常见,在网页里选一个文件,点击上传。上传到哪里?服务器咯。web和移动端本质上有区别嘛?木有啊,就是一个前端展示的client。那服务器会为移动端创造一套独立的API嘛?显然他没那么傻。
这个文件上传经常会伴随着其他fields一起上传。可以简单理解为表单上传。
先来看下,如果没有文件,也不用json,单独上传一些key value怎么做?在Postman里可以这样模拟。
表单上传要注意的是
content-type
设为application/x-www-form-urlencoded
form表单在streaming时是"weibo=stay4it&wechat=stay4it&qq=104816053"
多文件上传
实际上,多文件上传与form表单是一回事,一个key对应一个value。文件上传就是文件名key对应文件byte[] value,如下图postman模拟请求
只是如何标记一个key value的开始与结束呢?用&
分割肯定不够用啦。那就得用个特殊的boudary
来做为分隔符。
另外,这个content-type
得为multiple/form-data
好了。科普到此结束。简单理解HTTP协议以及form表单概念,相信接下来的代码你就不只是会调用,还能明白为什么。
最原始的上传方式
以前大家都用HttpUrlConnection,Stay在自己动手写HTTP框架-19课时详细讲过如何上传多文件以及进度更新。这里贴下核心代码:
以上这个UploadUtil,拿到outputstream,分别写入postContent
以及List<FileEntity>,代码不多,相信大家都能看明白。
抓个包看看
请求数据抓包
上传的有两个form,
一个content-type
为text/plain
key为data
, value为stay4it
。
一个content-type
为image/png
key为file0
, value为文件的bytes
服务器如何接收的?(PHP版)
代码还算好懂,$_FILES就是请求上传的多文件,只要content-type
设置为multiple/form-data
,服务器接收是就会将其当成文件处理,将文件接收在$_FILES
中,等待处理(存数据库,存硬盘或转七牛云等等),$this->data是表单中key为data
所对应的valuestay4it
。(以后再有服务器er告诉你分两个API上传,你就可以这么怼他了: )
返回结果抓包
好了,原始的方式聊的差不多了,虽然代码看起来很多,但已经是个util类了,倒不是那么难用。但是我们还是希望在写代码时能尽可能少的去关注内部实现啊。什么multiple/form-data
,什么boundary
。真是很麻烦嘛。
鸟枪换大炮吧
以下Retrofit多文件上传内容由一叶飘舟大神提供。
Retrofit实现文件和图片一起上传
如果对retrofit不是很了解,参考:初识Retrofit
定义接口
根据对Stay自己动手写HTTP框架-19课时提供的上传图片接口的大量抓包和测试总结,接口定义如下:
这里用到了@Partmap注解,将图片文件信息放入map中。
准备图片
在sdcard根目录存放两张图片,分别为test.png和test.jpg(不要是gif图片啊,服务器不支持)
代码实现
这里就不贴代码了,截图如下(如果看不清,鼠标右键在新窗口打开就可以看到原图了):
关键代码在于:
看到这个是不是想起了上面我们提到的关键代码呢?下面再贴出来我们对比下。
只要将对应的http请求头信息填写正确,就能上传成功。
那么问题又来了,怎么分析和正确拼写这个请求头呢?
在文章开头的时候有个抓包信息:
Content-Disposition: form-data; name="file0"; filename="test.png"
实质上上传文件Requestbody对应的请求头就是 name="file0"; filename="test.png",只要拼对了就没有问题了。
注意:
name="file0"; filename="test.png"这个请求头是根据有心课堂提供的上传接口写的,不适用其他上传接口,但原理是类似的;
单张图片上传通用的请求头是:name="file"; filename="test.png"
filename="test.png"这个一般是指(你希望)保存在服务器的文件名字。
举例说明
比如我们这样写请求头信息,如下代码所示:
运行请求抓包请求头信息如下图所示:
出现了name="name="file1"这样的字段,拼接错误(不用加name字段),服务器也毫不留情的返回了错误:
这个问题我当初没有发现,后来还是请教了Stay才搞明白了。
好了,不知道我讲的大家明白了没有,最后来个成功运行的请求抓包截图吧:
关于文字类参数上传
写到最后忘了说文字参数了,文字参数相对文件来说容易些。
在接口中,我们有一个文字参数 @Part("data") String des
,如果你需要多个,增加就行了。需要注意的是这个参数的名字比如"data",不是前端自定义,而是后台定义的。
代码托管地址:
https://github.com/stay4it/RetrofitTutorial
2016.8.19 凌晨
- 朋友圈上传图片+文字怎么破?
- 仿朋友圈上传图片
- 朋友圈实现图片+文字转发
- 分享图片+文字到微信朋友圈
- 微信朋友圈的图片上传,多图上传怎么去撸才合适?我们一起来实现吧!
- 微信朋友圈的图片上传,多图上传怎么去撸才合适?我们一起来实现吧!
- **张鸿洋**封装的okhttputils 上传文字加图片 实现发表朋友圈效果
- Android仿微信朋友圈上传图片
- Android仿微信朋友圈发图片和文字
- 上传图片和文字
- JavaScript怎么上传图片
- Android开发:分享文字跟多张图片到微信朋友圈
- android 系统自带分享文字+图片到微信朋友圈
- 微信分享多个图片和文字到朋友圈
- Android同时分享多张图片和文字到微信朋友圈
- 同时上传图片与文字
- Android实现多图上传 QQ发说说图片上传 朋友圈图片上传
- 怎么上传不了图片啊
- 设计模式之工厂方法模式
- Template模式(模板模式 行为型)
- 更新Cocoapods最新版与使用
- Unity3D脚本学习笔记3
- flex在安卓4.3中的兼容方式
- 朋友圈上传图片+文字怎么破?
- rpmbuild制作rpm安装包
- 如何应用正则表达式,正则表达式的应用
- JS 点击复制Copy
- 导航栏隐藏 && 导航栏错乱
- 矩阵乘法的Map-Reduce实现
- tomcat 同时部署两个WEB项目时的问题
- spring AOP @Around @Before @After 区别
- 自定义view系列(3)--给自定义View添加点击事件