form的enctype属性:客户端浏览器对form的编码方式。
客户端浏览器把form编码后,再发送给服务器处理。常见的设置有application/x-www-form-urlencoded和multipart/form-data两种,默认为前者。
application/x-www-form-urlencoded方式:不涉及文件传输时,一般设置为这种方式。根据w3c标准,这种编码方式如下编码:
空格被替换成“+”,非字母数字字符替换了`%HH',一个百分号和两个代表的ASCII码十六进制数字字符,换行表示为“CR LF”对。names/values对最后以“=”连接内部,以“&”分隔外部。
multipart/form-data方式:如果需要传输大量的二进制数据或者传输非ASCII文本时,需要采用这种编码方式。这种编码方式如下编码:
把form的内容分割成段,每段代表一个input属性,每个段落间用分隔符隔开。其中每个段落记录这个段落的信息,例如Content-Disposition,name,Content-Type等等,还有这个段落与下个段落的分隔符boundary,以及这个段落的value数据。
例如,这个form:
<FORM action=""
enctype="multipart/form-data"
method="post">
姓名:<INPUT type="text" name="name"><BR>
文件: <INPUT type="file" name="files"><BR>
<INPUT type="submit" value="Send"> <INPUT type="reset">
</FORM>
如果填入姓名为“user”,上传一个名称为image.jpg的文件后提交,这个form将被编码成如下(实际中没有行号):
1 Content-Type: multipart/form-data; boundary=AaB03x
2
3 --AaB03x
4 Content-Disposition: form-data; name="name"
5
6 user
7 --AaB03x
8 Content-Disposition: form-data; name="files"
9 Content-Type: image/pjpeg; boundary=BbC04y
10
11 ... image.jpg的内容...
12 --BbC04y--
13 --AaB03x--
各行解析如下:
1. 设置form的编码类型和分隔符。
2. 无
3. 一个form段(form自身的设置)的结束标记
4. “姓名”段的基本设置
5. 无
6. “姓名”段的值
7. 一个form段(姓名段)的结束标记
8. “文件”段的基本设置
9. “文件”段的高级设置 Content-Type设置这一段的”值”(image.jpg的byte[]数据)的解析方式。即服务器端接收到这段byte[]后,解析为文件时选择的mime类型。boundary设置文件段的分隔符,这个分隔符用在有多个文件上传时,文件之间的分隔标志。
10. 无
11. image.jpg的内容
12. 一个文件段(image.jpg)的结束标记
13. 一个form段(文件段)的结束标记。
关于第9步的Content-Type:
在Struts开发中,文件上传一般在前台使用html:file标签,在ActionForm的org.apache.struts.upload.FormFile接口来接收,FormFile接口提供的一个方法:getContentType()。这个方法的作用就是获取这里的Content-Type。