含义 ENCTYPE="multipart/form-data" 说明:
通过 http 协议上传文件 rfc1867协议概述,jsp 应用举例,客户端发送内容构造
1、
概述在最初的 http 协议中,没有上传文件方面的功能。 rfc1867
(http://www.ietf.org/rfc/rfc1867.txt) 为 http 协议添加了这个功能。客户端的浏览器,如
Microsoft IE, Mozila, Opera 等,按照此规范将用户指定的文件发送到服务器。服务器端的网页程序,如 php, asp,
jsp 等,可以按照此规范,解析出用户发送来的文件。Microsoft IE, Mozila, Opera
已经支持此协议,在网页中使用一个特殊的 form 就可以发送文件。绝大部分 http server ,包括 tomcat
,已经支持此协议,可接受发送来的文件。各种网页程序,如 php, asp, jsp 中,对于上传文件已经做了很好的封装。
2、上传文件的实例:用 servelet 实现(http server 为 tomcat 4.1.24)1. 在一个 html 网页中,写一个如下的form :
<formenctype="multipart/form-data"action="http://192.168.29.65/UploadFile"method=post>
loadmultifiles:<br>
<inputname="userfile1"type="file"><br>
<inputname="userfile2"type="file"><br>
<inputname="userfile3"type="file"><br><inputname="userfile4"type="file"><br>
textfield:<inputtype="text"name="text"value="text"><br>
<inputtype="submit"value="提交"><inputtype=reset></form>
用户可以选择多个文件,填写表单其它项,点击“提交”按钮后就开始上传给 http://192.168.29.65/upload_file/UploadFile
这是一个 servelet 程序注意 enctype="multipart/form-data", method=post,
type="file" 。根据 rfc1867, 这三个属性是必须的。multipart/form-data
是新增的编码类型,以提高二进制文件的传输效率。具体的解释请参阅 rfc18672. 服务端 servelet 的编写现在第三方的 http
upload file 工具库很多。Jarkata 项目本身就提供了fileupload
包http://jakarta.apache.org/commons/fileupload/ 。
文件上传、表单项处理、效率问题基
本上都考虑到了。在 Struts 中就使用了这个包,不过是用 Struts 的方式另行封装了一次。这里我们直接使用 fileupload
包。至于Struts 中的用法,请参阅 Struts 相关文档。这个处理文件上传的 servelet 主要代码如下:
publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)
{
DiskFileUploaddiskFileUpload=newDiskFileUpload();//允许文件最大长度
diskFileUpload.setSizeMax(100*1024*1024);//设置内存缓冲大小
diskFileUpload.setSizeThreshold(4096);//设置临时目录
diskFileUpload.setRepositoryPath("c:/tmp");
ListfileItems=diskFileUpload.parseRequest(request);
Iteratoriter=fileItems.iterator();for(;iter.hasNext();)
{
FileItemfileItem=(FileItem)iter.next();
if(fileItem.isFormField()){//当前是一个表单项
out.println("formfield:"+fileItem.getFieldName()+","+fileItem.getString());
}else{
//当前是一个上传的文件
StringfileName=fileItem.getName();
fileItem.write(newFile("c:/uploads/"+fileName));
}
}}
为简略起见,异常处理,文件重命名等细节没有写出。3、 客户端发送内容构造假设接受文件的网页程序位于
http://192.168.29.65/upload_file/UploadFile.假设我们要发送一个二进制文件、一个文本框表单项、一个密码
框表单项。文件名为 E:/s ,其内容如下:(其中的XXX代表二进制数据,如 01 02 03)abbXXXccc 客户端应该向
192.168.29.65 发送如下内容:
POST/upload_file/UploadFileHTTP/1.1
Accept:text/plain,*/*
Accept-Language:zh-cn
Host:192.168.29.65:80
Content-Type:multipart/form-data;boundary=---------------------------7d33a816d302b6
User-Agent:Mozilla/4.0(compatible;OpenOffice.org)
Content-Length:424
Connection:Keep-Alive-----------------------------7d33a816d302b6
Content-Disposition:form-data;
name="userfile1";
filename="E:/s"Content-Type:
application/octet-streamabbXXXccc
-----------------------------7d33a816d302b6
Content-Disposition:form-data;
name="text1"foo
-----------------------------7d33a816d302b6
Content-Disposition:form-data;
name="password1"bar
-----------------------------7d33a816d302b6--
(上面有一个回车)此内容必须一字不差,包括最后的回车。
注意:Content-Length: 424 这里的424是红色内容的总长度(包括最后的回车)
注意这一行:Content-Type: multipart/form-data; boundary=---------------------------7d33a816d302b6
根据 rfc1867, multipart/form-data是必须的.---------------------------7d33a816d302b6 是分隔符,分隔多个文件、表单项。
其中33a816d302b6 是即时生成的一个数字,用以确保整个分隔符不会在文件或表单项的内容中出现。前面的 ---------------------------7d 是 IE 特有的标志。
Mozila 为---------------------------71用手工发送这个例子,在上述的 servlet 中检验通过。
使用POST发送数据
以POST方式发送数据主要是为了向服务器发送较大量的客户端的数据,它不受URL的长度限制。POST请求将数据以URL编码的形式放在HTTP正文
中,字段形式为fieldname=value,用&分隔每个字段。注意所有的字段都被作为字符串处理。实际上我们要做的就是模拟浏览器POST
一个表单。以下是IE发送一个登陆表单的POST请求:
POSThttp://127.0.0.1/login.doHTTP/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;MSIE6.0;WindowsNT5.1)
Content-Length:28
/r/n
username=admin&password=1234
要在MIDP应用程序中模拟浏览器发送这个POST请求,首先设置HttpConnection的请求方式为POST:
hc.setRequestMethod(HttpConnection.POST);
然后构造出HTTP正文:
byte[]data="username=admin&password=1234".getBytes();
并计算正文长度,填入Content-Type和Content-Length:
hc.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
hc.setRequestProperty("Content-Length",String.valueOf(data.length));
然后打开OutputStream将正文写入:
OutputStreamoutput=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:
hc.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=...//文件内容
StringBOUNDARY="---------------------------7d4a6d158c9";//分隔符
StringBuffersb=newStringBuffer();
//发送每个字段:
for(inti=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...
分享到:
相关推荐
网上关于使用python 的发送multipart/form-data的方法,多半是采用 ulrlib2 的模拟post方法,如下: import urllib2\nboundary='-------------------------7df3069603d6' data=[] data.append('--%s' % boundary) ...
今天小编就为大家分享一篇python处理multipart/form-data的请求方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
multipart/form-data的数据由多个part组成,part间通过boundary分隔符进行分割,每个part由header和content组成 multipart/form-data的格式大致为: ----------------------------904587217962624105581666 ...
一个很小的,无依赖的节点模块,用于为POST请求生成表单的multipart / form-data主体。 这意味着它是一个简单的,没有多余的装饰的模块,用于生成要作为POST请求的主体发送的字符串,以模拟表单提交。 如果您需要...
HttpListener、HttpWebRequest的应用,包括如何解析POST请求中Body的数据(multipart/form-data)、如何构造multipart/form-data; boundary=的ContentType等技巧
webbench加上帖子 ... 2.Content-Type:multipart / form-data; boundary = random_bytes_or_numbers webbench --post文件名--file --header header1:value1 --header header2:value2 -t time -c数字
而post图片则是自己构造http协议数据,将http协议头的Content-Type设为multipart/form-data,同时还要加上 boundary=xxxxxxx(xxxxxxx表示一个字符串),后面的协议数据内容将要以这个xxxxxxx来进行分隔。...
而post图片则是自己构造http协议数据,将http协议头的Content-Type设为multipart/form-data,同时还要加上 boundary=xxxxxxx(xxxxxxx表示一个字符串),后面的协议数据内容将要以这个xxxxxxx来进行分隔。...
form action="/servlet/ReceiveServlet" ENCTYPE="multipart/form-data" method=post > C)提交请求 提交请求的过程由浏览器完成的,并且遵循 HTTP 协议,每一个从浏览器端到服务器端的一个请求,都包含了...
带进度条上传代码,适合学习参考资料,也可直接使用到项目中. 代码片段: Private Sub Class_Initialize() Set Files = Server.... Exit Sub ''如果form中没有包括multipart/form-data上传是无效的 End If
//conn.setRequestProperty("Content-Type","multipart/form-data;"); //设置边界 String BOUNDARY = "----------" + System.currentTimeMillis(); conn.setRequestProperty("Content-Type","multipart/form-...
m_contentType.StartsWith("multipart/form-data", StringComparison.OrdinalIgnoreCase)) return; if (!m_workRequest.HasEntityBody()) return; #endregion #region 获取分隔符 string m_boundaryStr = m_...
mongodb_cache_system 获取所有缓存-端点-/ api / v1 /... PUT缓存-{方法:'PUT',网址:'/ api / v1 / cache /',标头:{'content-type':'multipart / form-data; boundary = ---- WebKitFormBoundary7MA4YWxkTrZu0g
Content-Type(内容类型),一般是指网页中存在的 Content-Type,用于定义网络文件的类型和网页的编码,决定...Content-Type: multipart/form-data; boundary=something 实例: 常见的媒体格式类型如下: text/ht
Content-Type: multipart/form-data; boundary=---------------------------7d423a138d0278 Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)...
名称 ...概要 ... ... boundary => $boundary, on_header => $on_header, ...HTTP :: MultiPartParser是低级的multipart / form-data解析器库。 该库是chansen用于Perl5的HTTP :: MultiPartParser的端口。 方法 新的 $parser
String CONTENT_TYPE = "multipart/form-data"; // 内容类型 try { URL url = new URL(RequestURL); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setReadTimeout(TIME_...
通用用法 但上图的字段名,类型需要根据不同接口... # Content-Type: multipart/form-data; boundary=alamofire.boundary.3c7024a080e6a27f, #注意,此处不要写Content-Type apiVersion: v1.0.0, appVersion: v1.0.0,
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data;boundary=%@",boundary]; [request addValue:contentType forHTTPHeaderField: @"Content-Type"]; // NSMutableData *body = ...