其实我们这种前后台的交互是用的HTTP协议。而http协议默认是传的字符串。所以我们上传文件的话要加enctype = "multipart/form-data"这个参数来说明我们这传的是文件不是字符串了。而我们做web开发的时候,浏览器是自动解析HTTP协议的。里面传的哪些东西我们不用管。只要记住几个参数就行。而我们要上传的文件报文是保存在请求的头文件里面的。下面就是上传文件头文件的格式:
POST/logsys/home/uploadIspeedLog!doDefault.html HTTP/1.1
Accept: text/plain, */*
Accept-Language: zh-cn
Host: 192.168.24.56
Content-Type:multipart/form-databoundary=-----------------------------7db372eb000e2
User-Agent: WinHttpClient
Content-Length: 3693
Connection: Keep-Alive
-------------------------------7db372eb000e2
Content-Disposition: form-dataname="file"filename="kn.jpg"
Content-Type: image/jpeg
(此处省略jpeg文件二进制数据...)
-------------------------------7db372eb000e2--
这就是Http上传发送的文件格式。而我们要发送的时候必然要遵循这种格式来并且不能出一点差错包括每行后面的回车,下面一段文字是网上找的感觉写的比较精彩。(尊重原创:原文地址)
红色字体部分就是协议的头。给服务器上传数据时,并非协议头每个字段都得说明,其中,content-type是必须的,它包括一个类似标志性质的名为boundary的标志,它可以是随便输入的字符串。对后面的具体内容也是必须的。它用来分辨一段内容的开始。Content-Length: 3693 ,这里的3693是要上传文件的总长度。绿色字体部分就是需要上传的数据,可以是文本,也可以是图片等。数据内容前面需要有Content-Disposition, Content-Type以及Content-Transfer-Encoding等说明字段。最后的紫色部分就是协议的结尾了。
注意这一行:
Content-Type: multipart/form-databoundary=---------------------------7db372eb000e2
根据 rfc1867, multipart/form-data是必须的.
---------------------------7db372eb000e2 是分隔符,分隔多个文件、表单项。其中b372eb000e2 是即时生成的一个数字,用以确保整个分隔符不会在文件或表单项的内容中出现。Form每个部分用分隔符分割,分隔符之前必须加上"--"着两个字符(即--{boundary})才能被http协议认为是Form的分隔符,表示结束的话用在正确的分隔符后面添加"--"表示结束。
前面的 ---------------------------7d 是 IE 特有的标志,Mozila 为---------------------------71.
每个分隔的数据的都可以用Content-Type来表示下面数据的类型,可以参考rfc1341
第一步:编写一个Servlet,把接收到的HTTP信息保存在一个文件中,代码如下:public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//获取输入流,是HTTP协议中的实体内容
ServletInputStream sis=request.getInputStream()
//缓冲区
byte buffer[]=new byte[1024]
FileOutputStream fos=new FileOutputStream("d://file.log")
int len=sis.read(buffer, 0, 1024)
//把流里的信息循环读入到file.log文件中
while( len!=-1 )
{
fos.write(buffer, 0, len)
len=sis.readLine(buffer, 0, 1024)
}
fos.close()
sis.close()
}
第二步:实现如下图1的的表单页面,生成一个注册表单,提交到Servlet中
详细的代码如下:
<form action="servlet/ReceiveFile" method="post" enctype="multipart/form-data">
第一个参数<input type="text" name="name1"/><br/>
第二个参数<input type="text" name="name2"/><br/>
第一个上传的文件<input type="file" name="file1"/><br/>
第二个上传的文件<input type="file" name="file2"/><br/>
<input type="submit" value="提交">
</form>
注意了,由于要上传附件,所以一定要设置enctype为multipart/form-data,才可以实现附件的上传。
第三步:填写完信息后按“提交”按钮后,在D盘下查找file.log文件用记事本打开,数据如下:
-----------------------------7d92221b604bc
Content-Disposition: form-dataname="name1"
hello
-----------------------------7d92221b604bc
Content-Disposition: form-dataname="name2"
world
-----------------------------7d92221b604bc
Content-Disposition: form-dataname="file1"filename="C:/2.GIF"
Content-Type: image/gif
GIF89a
服务器端写个servlet,然后在doPost()方法里处理客户端上传的文件,大概代码:DiskFileItemFactory factory = new DiskFileItemFactory()factory.setSizeThreshold(1024 * 1024)// 设置最多只允许在内存中存储的数据, 单位:字节factory.setRepository(cachepath)// 设置一旦文件大小超过设定值时数据存放的目录 ServletFileUpload srvFileUpload = new ServletFileUpload(factory)srvFileUpload.setSizeMax(1024 * 1024 * 1024)// 设置允许用户上传文件大小, 单位:字节// 开始读取上传信息List fileItems = nulltry { fileItems = srvFileUpload.parseRequest(request)} catch (Exception e) { System.out.println("获取上传信息。。。。。。失败")}// 依次处理每个上传的文件Iterator iter = fileItems.iterator()while (iter.hasNext()) { FileItem item = (FileItem) iter.next()// 忽略其他不是文件域的所有表单信息 if (!item.isFormField()) {// 取出文件域的所有表单信息 } else { // 取出不是文件域的所有表单信息 }}欢迎分享,转载请注明来源:内存溢出
评论列表(0条)