服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

用java servlet实现文件上载


  各位大侠可能会对263电子邮箱中的"上传附件"功能有印象,就是:在浏览 器中点击"浏览",弹出一个对话框,选中文件后,单击"确定",文件就被上传到了服务器端。 因为需要,就到网上找了几个控件,如smartupload等,但都觉得不好用,或者 说是不合用,决定自己做一个。近日看到网上也有人提问怎么上载文件,于是把编制过程整理一遍,希望对大家有所帮助,不足之处,请多多指教。 准备 侦听工具,如spynet(包括capturenetpeepnet),目的是用于分析数据包格式;

java环境:至少要包括一个servlet引擎,一套jdk;如果没有,可以访问这里

从这36款中随便找出一种来,安装运行即可。jsp服务器都会支持servlet,因为jsp本身就是先被编译成servlet再执行的。 过程

1、制作html页面,用于上传文件。需要注意:要指定enctype属性为"multipart/form-data",因为数据流的格式是不一样的。

<form action="/java/servlet/powerise.nms.web.uploadfile"
method=post enctype="multipart/form-data"> <p>
<input type=radio name=type value=0>model
<input type=radio name=type value=1>report <input name=id >
<input type=file name=file value="test"> </p>
<input type=submit> </form>

2、html页面做好后,就可以开始分析数据流了。先打开侦听器,然后在浏览器(ie, netscape)中打开本页面,随意选择一个文件,单击"确定",看看侦听器听到了什么。在跳过前面几个包后,可以得到下面这两个相关的包。

第一个包的很容易明白,在servlet中,用getheader(string)能得到的内容就在这里面。不过这个包,用httpservletrequest的getinputstream是得不到的。

关于http协议的更多信息,可以访问www.w3c.org。

0000: 00 e0 4c dd 2f 4f 00 50 ba a6 c3 cf 08 00 45 00 ..l./o.p......e.
0010: 02 3e 01 46 40 00 80 06 0e f5 ac 12 c8 01 ac 12 .>.f@...........
0020: c8 58 04 12 00 50 48 82 2a 39 fa 97 28 31 50 18 .x...ph.*9..(1p.
0030: 44 70 a4 76 00 00 50 4f 53 54 20 2f 6a 61 76 61 dp.v..post /java
0040: 2f 73 65 72 76 6c 65 74 2f 69 6d 63 2e 55 70 6c /servlet/imc.upl
0050: 6f 61 64 20 48 54 54 50 2f 31 2e 31 0d 0a 41 63 oad http/1.1..ac
0060: 63 65 70 74 3a 20 69 6d 61 67 65 2f 67 69 66 2c cept: image/gif,
0070: 20 69 6d 61 67 65 2f 78 2d 78 62 69 74 6d 61 70 image/x-xbitmap
0080: 2c 20 69 6d 61 67 65 2f 6a 70 65 67 2c 20 69 6d , image/jpeg, im
0090: 61 67 65 2f 70 6a 70 65 67 2c 20 61 70 70 6c 69 age/pjpeg, appli
00a0: 63 61 74 69 6f 6e 2f 76 6e 64 2e 6d 73 2d 70 6f cation/vnd.ms-po
00b0: 77 65 72 70 6f 69 6e 74 2c 20 61 70 70 6c 69 63 werpoint, applic
00c0: 61 74 69 6f 6e 2f 76 6e 64 2e 6d 73 2d 65 78 63 ation/vnd.ms-exc
00d0: 65 6c 2c 20 61 70 70 6c 69 63 61 74 69 6f 6e 2f el, application/
00e0: 6d 73 77 6f 72 64 2c 20 2a 2f 2a 0d 0a 52 65 66 msword, */*..ref
00f0: 65 72 65 72 3a 20 68 74 74 70 3a 2f 2f 31 37 32 erer: http://172
0100: 2e 31 38 2e 32 30 30 2e 38 38 2f 64 65 6d 6f 2f .18.200.88/demo/
0110: 74 65 73 74 2e 68 74 6d 6c 0d 0a 41 63 63 65 70 test.html..accep
0120: 74 2d 4c 61 6e 67 75 61 67 65 3a 20 7a 68 2d 63 t-language: zh-c
0130: 6e 0d 0a 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a n..content-type:
0140: 20 6d 75 6c 74 69 70 61 72 74 2f 66 6f 72 6d 2d multipart/form-
0150: 64 61 74 61 3b 20 62 6f 75 6e 64 61 72 79 3d 2d data; boundary=-
0160: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d ----------------
0170: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 37 64 31 33 35 32 ----------7d1352
0180: 61 32 30 31 36 63 0d 0a 41 63 63 65 70 74 2d 45 a2016c..accept-e
0190: 6e 63 6f 64 69 6e 67 3a 20 67 7a 69 70 2c 20 64 ncoding: gzip, d
01a0: 65 66 6c 61 74 65 0d 0a 55 73 65 72 2d 41 67 65 eflate..user-age
01b0: 6e 74 3a 20 4d 6f 7a 69 6c 6c 61 2f 34 2e 30 20 nt: mozilla/4.0
01c0: 28 63 6f 6d 70 61 74 69 62 6c 65 3b 20 4d 53 49 (compatible; msi
01d0: 45 20 35 2e 30 31 3b 20 57 69 6e 64 6f 77 73 20 e 5.01; windows
01e0: 4e 54 20 35 2e 30 29 0d 0a 48 6f 73 74 3a 20 31 nt 5.0)..host: 1
01f0: 37 32 2e 31 38 2e 32 30 30 2e 38 38 0d 0a 43 6f 72.18.200.88..co
0200: 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 3a 20 34 30 ntent-length: 40
0210: 39 0d 0a 43 6f 6e 6e 65 63 74 69 6f 6e 3a 20 4b 9..connection: k
0220: 65 65 70 2d 41 6c 69 76 65 0d 0a 43 6f 6f 6b 69 eep-alive..cooki
0230: 65 3a 20 4a 53 45 53 53 49 4f 4e 49 44 3d 63 74 e: jsessionid=ct
0240: 71 62 76 65 38 73 35 31 0d 0a 0d 0a qbve8s51....

再看第二个包,可以看到,所要传的参数都在。下文只分析这个包。

0000: 00 e0 4c dd 2f 4f 00 50 ba a6 c3 cf 08 00 45 00 ..l./o.p......e.
0010: 01 c1 01 47 40 00 80 06 0f 71 ac 12 c8 01 ac 12 ...g@....q......
0020: c8 58 04 12 00 50 48 82 2c 4f fa 97 28 31 50 18 .x...ph.,o..(1p.
0030: 44 70 3d ae 00 00 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d dp=...----------

↑(1)开始

0040: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d ----------------
0050: 2d 2d 2d 37 64 31 33 35 32 61 32 30 31 36 63 0d ---7d1352a2016c.
0060: 0a 43 6f 6e 74 65 6e 74 2d 44 69 73 70 6f 73 69 .content-disposi
0070: 74 69 6f 6e 3a 20 66 6f 72 6d 2d 64 61 74 61 3b tion: form-data;
0080: 20 6e 61 6d 65 3d 22 74 79 70 65 22 0d 0a 0d 0a name="type"....
0090: 30 0d 0a 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0..-------------

↑(2)第1段结束

00a0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d ----------------
00b0: 37 64 31 33 35 32 61 32 30 31 36 63 0d 0a 43 6f 7d1352a2016c..co
00c0: 6e 74 65 6e 74 2d 44 69 73 70 6f 73 69 74 69 6f ntent-dispositio
00d0: 6e 3a 20 66 6f 72 6d 2d 64 61 74 61 3b 20 6e 61 n: form-data; na
00e0: 6d 65 3d 22 69 64 22 0d 0a 0d 0a 36 37 38 0d 0a me="id"....678..
00f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d ----------------

↑(3)第2段结束

0100: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 37 64 31 -------------7d1
0110: 33 35 32 61 32 30 31 36 63 0d 0a 43 6f 6e 74 65 352a2016c..conte
0120: 6e 74 2d 44 69 73 70 6f 73 69 74 69 6f 6e 3a 20 nt-disposition:
0130: 66 6f 72 6d 2d 64 61 74 61 3b 20 6e 61 6d 65 3d form-data; name=
0140: 22 66 69 6c 65 22 3b 20 66 69 6c 65 6e 61 6d 65 "file"; filename
0150: 3d 22 43 3a 5c 43 4f 4e 46 49 47 2e 53 59 53 22 ="c:/config.sys"
0160: 0d 0a 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 ..content-type:
0170: 74 65 78 74 2f 70 6c 61 69 6e 0d 0a 0d 0a 73 68 text/plain....sh
0180: 65 6c 6c 3d 63 3a 5c 63 6f 6d 6d 61 6e 64 2e 63 ell=c:/command.c
0190: 6f 6d 20 2f 70 20 2f 65 3a 33 32 30 30 30 0d 0a om /p /e:32000..
01a0: 0d 0a 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d ..--------------

↑(4)第3段结束

01b0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 37 ---------------7
01c0: 64 31 33 35 32 61 32 30 31 36 63 2d 2d 0d 0a d1352a2016c--..

(5)结束 ↑
以下对各标号作出说明: (1)开始,这是整个能得到的输入流的开端;
(2)第1段结束。每一段包含一个参数的信息,这些信息包括类型、名称、内容等。 (3)和(4)与(2)是一样的。
(4)以后就是输入流的结束标志:boundary。 (5)为从输入流中能读到的最后一个字符。

注意了第一个包中,有一项叫做"boundary"。顾名思义,这个boundary是"分界"标志了。每一段的开头都会有一个boundary,然后是 0d 0a,然后是一些 相关信息,接着是 0d 0a 0d 0a,紧跟着参数的实际值,然后是下一个boundary,标志着下一段的开始。而整个输入流呢,以一个boundary结束。如果只有一个参数,那输入流的结构应该是下面这样的:

boundary 0d 0a ... 0d 0a 0d 0a ... boundary 0d 0a

↑ ↑ ↑ ↑

开始 参数的信息 参数的内容 结束

明白了数据

扫描关注微信公众号