上传文件multipart form-data boundary 说明

简介:

含义 ENCTYPE="multipart/form-data" 说明:

通过 http 协议上传文件 rfc1867协议概述,客户端发送内容构造。

概述                                                                                           

在最初的 http 协议中,没有上传文件方面的功能。 rfc1867为 http 协议添加了这个功能。客户端的浏览器,如 Microsoft IE, Mozila, Opera 等,按照此规范将用户指定的文件发送到服务器。服务器端的网页程序,如 php, asp, jsp 等,可以按照此规范,解析出用户发送来的文件。Microsoft IE, Mozila, Opera 已经支持此协议,在网页中使用一个特殊的 form 就可以发送文件。绝大部分 http server ,包括 tomcat ,已经支持此协议,可接受发送来的文件。各种网页程序,如 php, asp, jsp 中,对于上传文件已经做了很好的封装。

实例                                                                                           

<form action="upFile.php" enctype="multipart/form-data" method="post">
<input name="myflie" type="file" />
<input type="submit" />

注意 enctype="multipart/form-data", method=post, type="file" 。根据 rfc1867, 这三个属性是必须的。multipart/form-data 是新增的编码类型,以提高二进制文件的传输效率。

数据传输                                                                                      

格式 必须一字不差,包括最后的回车。

注意:Content-Length: 226 这里的226是红色内容的总长度(包括最后的回车)

注意这一行:

Content-Type: multipart/form-data; boundary=-----------------------------264141203718551

根据 rfc1867, multipart/form-data是必须的.---------------------------7d33a816d302b6 是分隔符,分隔多个文件、表单项。

其中7d33a816d302b6 是即时生成的字符串,用以确保整个分隔符不会在文件或表单项的内容中出现。

使用POST发送数据                                                                      

以POST方式发送数据主要是为了向服务器发送较大量的客户端的数据,它不受URL的长度限制。POST请求将数据以URL编码的形式放在HTTP正文中,字段形式为fieldname=value,用&分隔每个字段。注意所有的字段都被作为字符串处理。实际上我们要做的就是模拟浏览器POST 一个表单。以下是IE发送一个登陆表单的POST请求:

复制代码
POST http://127.0.0.1/login.do HTTP/1.0
Accept: image/gif, image/jpeg, image/pjpeg, */*
Accept-Language: en-us,zh-cn;q=0.5
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
Content-Length: 28
 
username=admin&password=1234
复制代码

要在MIDP应用程序中模拟浏览器发送这个POST请求,首先设置HttpConnection的请求方式为POST(PHP为curl):

// 使用POST方法
              httpURLConnection.setRequestMethod("POST");

然后构造出HTTP正文:

byte[] data = "username=admin&password=1234".getBytes();

并计算正文长度,填入Content-Type和Content-Length:

httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
httpURLConnection.setRequestProperty("Content-Length", String.valueOf(data.length));

然后打开OutputStream将正文写入:

OutputStream output = hc.openOutputStream();
output.write(data);

需要注意的是,数据仍需要以URL编码格式编码,由于MIDP库中没有J2SE中与之对应的URLEncoder类,因此,需要自己动手编写这个 encode()方法,可以参考java.net.URLEncoder.java的源码。剩下的便是读取服务器响应,代码与GET一致,这里就不再详述。

使用multipart/form-data发送文件                                             

如果要在MIDP客户端向服务器上传文件,我们就必须模拟一个POST multipart/form-data类型的请求,Content-Type必须是multipart/form-data。

以multipart/form-data编码的POST请求格式与application/x-www-form-urlencoded完全不同,multipart/form-data需要首先在HTTP请求头设置一个分隔符,例如ABCD:

httpURLConnection.setRequestProperty("Content-Type", "multipart/form-data; boundary=ABCD");

然后,将每个字段用“--分隔符”分隔,最后一个“--分隔符--”表示结束。例如,要上传一个title字段"Today"和一个文件C:\1.txt,HTTP正文如下:

复制代码
--ABCD
Content-Disposition: form-data; name="title"
\r\n
Today
--ABCD
Content-Disposition: form-data; name="1.txt"; filename="C:\1.txt"
Content-Type: text/plain
\r\n
<这里是1.txt文件的内容>
--ABCD--
\r\n
复制代码

请注意,每一行都必须以\r\n结束,包括最后一行。如果用Sniffer程序检测IE发送的POST请求,可以发现IE的分隔符类似于 ---------------------------7d4a6d158c9,这是IE产生的一个随机数,目的是防止上传文件中出现分隔符导致服务器无法正确识别文件起始位置。我们可以写一个固定的分隔符,只要足够复杂即可。

发送文件的POST代码如下:

复制代码
String[] props = ... // 字段名
String[] values = ... // 字段值
byte[] file = ... // 文件内容
String BOUNDARY = "---------------------------7d4a6d158c9"; // 分隔符
StringBuffer sb = new StringBuffer();
// 发送每个字段:
for(int i=0; i
sb = sb.append("--");
sb = sb.append(BOUNDARY);
sb = sb.append("\r\n");
sb = sb.append("Content-Disposition: form-data; name=\""+ props[i] + "\"\r\n\r\n");
sb = sb.append(URLEncoder.encode(values[i]));
sb = sb.append("\r\n");
}
// 发送文件:
sb = sb.append("--");
sb = sb.append(BOUNDARY);
sb = sb.append("\r\n");
sb = sb.append("Content-Disposition: form-data; name=\"1\"; filename=\"1.txt\"\r\n");
sb = sb.append("Content-Type: application/octet-stream\r\n\r\n");
byte[] data = sb.toString().getBytes();
byte[] end_data = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();
// 设置HTTP头:
hc.setRequestProperty("Content-Type", MULTIPART_FORM_DATA + "; boundary=" + BOUNDARY);
hc.setRequestProperty("Content-Length", String.valueOf(data.length + file.length + end_data.length));
// 输出:
output = hc.openOutputStream();
output.write(data);
output.write(file);
output.write(end_data);
// 读取服务器响应:
// TODO...
复制代码

 




本文转自我爱物联网博客园博客,原文链接:http://www.cnblogs.com/yydcdut/p/3736667.html,如需转载请自行联系原作者

相关文章
|
自然语言处理 安全 C++
【C++ 格式化输出 】C++20 现代C++格式化:拥抱std--format简化你的代码
【C++ 格式化输出 】C++20 现代C++格式化:拥抱std--format简化你的代码
10605 4
|
Java API Android开发
Android 最新实现沉浸式状态栏的效果
Android 最新实现沉浸式状态栏的效果
695 0
|
人工智能 小程序 前端开发
【uniapp小程序】uploadFile文件上传
【uniapp小程序】uploadFile文件上传
2192 0
|
11月前
|
JSON JavaScript 前端开发
HarmonyOS NEXT实战:接入和使用axios
HarmonyOS Next 实战中,使用 Axios 可实现高效网络请求。Axios 是基于 Promise 的库,支持 GET、POST 等方法,并具备拦截器、自动 JSON 转换等功能。适配 OpenHarmony 后,仍保留其原有特性。需安装 @ohos/axios 并配置网络权限,可创建工具类统一管理请求与响应。
539 0
|
Java API 容器
理解HTTP协议中的multipart/form-data
之前在写一个通用HTTP组件的时候遇到过媒体(Media)类型multipart/form-data的封装问题,这篇文章主要简单介绍一下HTTP协议中媒体类型multipart/form-data的定义、应用和简单实现。
2016 0
理解HTTP协议中的multipart/form-data
|
安全 开发工具 Android开发
【Android Git】Git版本回退方式
在实际操作中,选择合适的版本回退方式,可以有效地管理代码版本,提高开发效率和代码质量。
794 26
|
存储 边缘计算 运维
移动LTE背后:核心网络详解
移动LTE背后:核心网络详解
1407 4
|
前端开发 JavaScript
npm : 无法将“npm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称
npm : 无法将“npm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称
1766 0
|
存储 安全 算法
C#一分钟浅谈:数据加密与解密技术
【10月更文挑战第3天】在数字化时代,信息安全至关重要。数据加密作为保障信息不被未授权访问的有效手段,通过特定算法将明文转换为密文,确保即使数据被截获也难以解读。本文从基础概念入手,介绍C#中实现数据加密的方法,涵盖对称加密(如AES、DES)与非对称加密(如RSA),并通过具体示例代码演示如何使用`System.Security.Cryptography.Aes`类完成AES加密和解密过程。此外,还强调了密钥管理及安全策略的重要性。
351 4
|
物联网 开发者
如何在StableDiffusionWebUI 中使用Civital网站的LoRA模型?
如何在StableDiffusionWebUI 中使用Civital网站的LoRA模型?
1511 0