Andoid - 开发实例(5):上传文件实现方法
来源:互联网 发布:创新的社会网络 编辑:程序博客网 时间:2024/05/20 11:25
一月份做项目时 Android 客户端需要上传图片,小小的研究了下,不改独享,分享!
如果要在客户端向服务器上传文件,我们就必须模拟一个POST multipart/form-data类型的请求,Content-Type必须是multipart/form-data
这篇详细介绍这个 ENCTYPE="multipart/form-data" 协议,来解决自己的Java程序向服务器传文件的问题(比如:安卓程序上传图片)
ENCTYPE="multipart/form-data" :通过 http 协议上传文件 rfc1867协议,客户端发送内容构造。
<form action="picture/upload.do" method="POST" ENCTYPE="multipart/form-data">
<input type="text" name="users_id">
<input type="text" name="users_name">
<input type="file" name="image_path">
<input type="submit">
</form>
使用上面这个表单,抓包的结果如下
POST /picture/upload.do HTTP/1.1
Accept: application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, */*
Referer: http://192.168.1.98:8080/uploadpic.jsp
Accept-Language: zh-CN
User-Agent: Mozilla/4.0
Content-Type: multipart/form-data; boundary=---------------------------7dd36df20300
Accept-Encoding: gzip, deflate
Host: 192.168.1.98:8080
Content-Length: 529762
Connection: Keep-Alive
Cache-Control: no-cache
-----------------------------7dd36df20300
Content-Disposition: form-data; name="users_id"
<!--空行-->
1
-----------------------------7dd36df20300
Content-Disposition: form-data; name="users_name"
<!--空行-->
admin
-----------------------------7dd36df20300
Content-Disposition: form-data; name="image_path"; filename="S21223-170317.jpg"
Content-Type: image/pjpeg
<!--空行-->
<!--文件 byte 数据-->
-----------------------------7dd36df20300--
<!--空行-->
详细解析:
Content-Type: multipart/form-data; boundary=---------------------------7dd36df20300
根据 rfc1867, multipart/form-data是必须的。
---------------------------7dd36df20300 是分隔符,分隔多个文件、表单项。
其中 d36df20300 是即时生成的一个字符,用以确保整个分隔符不会在文件或表单项的内容中出现。
---------------------------7d IE内核标志
---------------------------71 Mozila内核标志
---------------------------71 Mozila内核标志
从请求体里可以看出每一条数据后面都有换行 \r\n ,并且 Parameter 和 value 之间还有个空行
最后把格式提取:
--分隔符 \r\n
Content-Disposition: form-data; name="[Parameter]" \r\n
\r\n
[value] \r\n
--分隔符 \r\n
Content-Disposition: form-data; name="[Parameter]"; filename="[]" \r\n
Content-Type: image/pjpeg \r\n
\r\n
<!--文件 byte 数据--> \r\n
--分隔符-- \r\n
\r\n
了解了传输格式,接下来就是程序实现:
String path = "http://192.168.1.102:8080/picture/upload.do";
// 换行符
String enter = "\r\n";
// 分割线
String boundary = "---------------------------7dd36df20300";
StringBuffer sb = new StringBuffer();
// 获取文件流
File file = new File("D:\\123.jpg");
FileInputStream is = new FileInputStream(file);
// 参数信息
String[] keys = { "users_id", "users_name" };
String[] values = { "1", "admin" };
// 拼凑参数
for (int i = 0; i < keys.length; i++) {
sb.append("--" + boundary + enter);
sb.append("Content-Disposition: form-data; name=\"" + keys[i] + "\"");
sb.append(enter + enter);
sb.append(values[i]);
sb.append(enter);
}
// 拼凑文件头部信息
sb.append("--" + boundary);
sb.append(enter);
sb.append("Content-Disposition: form-data; name=\"image_path\"; filename=\"123.jpg\"");
sb.append(enter);
sb.append("Content-Type: image/*");
sb.append(enter + enter);
byte[] data = sb.toString().getBytes();
byte[] end_data = (enter + "--" + boundary + "--" + enter + enter).getBytes();
// 初始化 HttpURLConnection
URL url = new URL(path);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setConnectTimeout(3000);
con.setDoInput(true);
con.setDoOutput(true);
con.setUseCaches(false);
con.setRequestMethod("POST");
con.setRequestProperty("Connection", "Keep-Alive");
con.setRequestProperty("Charset", "UTF-8");
con.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
con.setRequestProperty("Content-Length", file.length() + data.length
+ end_data.length + "");
// 开始上传
OutputStream outputStream = con.getOutputStream();
outputStream.write(data);
byte[] fileBuffer = new byte[1024];
int length = -1;
while ((length = is.read(fileBuffer)) != -1) {
outputStream.write(fileBuffer, 0, length);
}
is.close();
outputStream.write(end_data);
outputStream.flush();
outputStream.close();
con.getResponseCode();
- Andoid - 开发实例(5):上传文件实现方法
- Andoid - 开发实例(4):简易在线聊天实现 (Client+Server)
- Andoid - 开发实例(4):简易在线聊天实现 (Client+Server)
- Andoid - 开发实例(4):简易在线聊天实现 (Client+Server)
- Andoid - 开发实例(6):动画实例之实现Google+滑动Listview让底部bar隐藏
- Andoid - 开发实例(3):高仿微信的界面
- Andoid - 开发实例(7):JNI.NDKHelloWorld
- aspx实现上传文件实例
- socket 实现文件上传实例
- FormData 实现文件上传实例
- Andoid - 开发实例(1): ViewPager卡片式界面
- Andoid - 开发实例(2): ViewPager卡片式界面2
- php实现上传文件方法
- Struts2.0实现单个文件上传实例
- Common-FileUpload实现文件上传,实例一
- [PHP实例] PHP多文件上传实现
- commons-fileupload实现文件上传功能实例
- commons-fileupload实现文件上传功能实例
- socket in java -client
- Oracle数据库存储结构
- lua manual翻译——第三章第三、四节 堆栈操作
- 云存储——asus webstorage
- 最好使用C++转型操作符
- Andoid - 开发实例(5):上传文件实现方法
- 贝叶斯分类器--原理流程应用
- binder小例子
- 微信开放了server端,互联网小站商业模式突破的福音
- spring注入问题
- net错误:Process performance counter is disabled,so the requested operation cannot be performed
- Javascript 给页面元素添加事件函数探讨
- Java/PHP/C ... 几种语言 RSA 的互操作
- MPEG-2 数字视频技术参考指南 (1) —— 前言