Commons FileUpload

一) 基础简介:
1、FileUpload 是 Apache commons下面的一个子项目,用来实现Java环境下面的[b]文件上传功能[/b],与常见的SmartUpload齐名。
2、组件FileUpload依赖于Commons IO组件。 目前FileUpload的最新版本是1.2.2 ,对于此版本官方推荐的依赖的IO组件版本是1.3.2
3、FileUpload 是基于RFC1867协议实现的。
4、API: [url]http://commons.apache.org/fileupload/apidocs/index.html[/url]

二)RFC1867协议:
RFC1867协议作为HTTP协议的附加协议,详细描述了File Upload的规则。RFC1867协议主要是在HTTP协议的基础上为INPUT标签增加了file属性,同时限定了Form的method必须为POST,ENCTYPE必须为multipart/form-data,当然还增加了一些与此相关属性。
比如value属性表示默认的上传文件的文件名(无文件上传时生效)
width表示默认的显示文件名的长度
height表示显示上传文件的个数

[b][size=large]例子:[/size][/b]
<FORM ACTION="http://server.dom/cgi/handle" ENCTYPE="multipart/form-data" METHOD=POST>
What is your name? <INPUT TYPE=TEXT NAME=field1>
What files are you sending? <INPUT TYPE=FILE NAME=pics>
</FORM>
假设用户在name一栏里输入"Joe Blow",上传了一个文件名叫"file1.txt"的文件。那么浏览器将发送的包格式会是这样:
Content-type: [b]multipart/form-data[/b], boundary=AaB03x

--AaB03x
content-disposition: form-data; name="field1"

Joe Blow
--AaB03x
content-disposition: form-data; [b]name="pics"; filename="file1.txt"[/b]
Content-Type: text/plain

... contents of file1.txt ...
--AaB03x--
如果上传的文件中还包含一个叫"file2.gif"的图片,那么包格式将会是这样:
Content-type: multipart/form-data, boundary=AaB03x

--AaB03x
content-disposition: form-data; name="field1"

Joe Blow
--AaB03x
content-disposition: form-data; name="pics"
[b]Content-type: multipart/mixed, boundary=BbC04y[/b]

--BbC04y
Content-disposition: attachment; filename="file1.txt"
[b]Content-Type: text/plain[/b]

... contents of file1.txt ...
--BbC04y
Content-disposition: attachment; filename="file2.gif"
[b]Content-type: image/gif[/b]
Content-Transfer-Encoding: binary

...contents of file2.gif...
--BbC04y--
--AaB03x--

[b][size=large]总结:[/size][/b]
RFC1867对HTTP头作了适当地变更,但变更很小。首先content-type头由以前的:
content-type: application/x-www-form-urlencoded
变为
content-type: multipart/form-data; +空格+ boundary=AaB03x
即增加了boundary,所谓的boundary其实就是分割线,RFC1867利用boundary分割HTTP实体数据。boundary中数字字符区是随机生成的。

三)代码样例:
[b]最简单的一个例子:[/b]

// Create a factory for disk-based file items
FileItemFactory factory = new DiskFileItemFactory();
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
// Parse the request
List <FileItem> items = upload.parseRequest(request);

如上我们就把request的所有信息包括上传文件的信息都转换到items这个对象里去了。

[b]再增加一点点控制:[/b]

// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();
// Sets the size threshold beyond which files are written directly to disk.
factory.setSizeThreshold(yourMaxMemorySize);
// Sets the directory used to temporarily store files that are larger than the configured size threshold.
factory.setRepository(yourTempDirectory);
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
// Sets the maximum allowed size of a complete request
upload.setSizeMax(yourMaxRequestSize);
// Parse the request
List <FileItem> items = upload.parseRequest(request);


[b]FileItem的处理:[/b]

Iterator iter = items.iterator();
while (iter.hasNext()) {
FileItem item = (FileItem) iter.next();
if (item.isFormField()) { // Process a regular form field
String name = item.getFieldName();
String value = item.getString();
} else { // Process a file upload
String fieldName = item.getFieldName();
String fileName = item.getName();
String contentType = item.getContentType();
boolean isInMemory = item.isInMemory();
long sizeInBytes = item.getSize();
}
}

这里有必要对FileItem的一些方法做进一步的介绍:
[b]public boolean isFormField()[/b] -- 用于判断 FileItem 类对象封装的数据是否属于一个普通表单字段,还是属于一个文件表单字段,如果是普通表单字段则返回 true,否则返回 false。
[b]public String getName()[/b] -- 依据RFC1867协议返回的是filename的内容。以上文例子为例,返回值将是“file1.txt” 或 “file2.gif”。如果 FileItem 类对象对应的是普通表单字段,getName 方法将返回 null。
[b]public String getFieldName()[/b] -- 依据RFC1867协议返回的是name的内容。以上文例子为例,返回值将是“field1” 或 “pics”。
[b]public void write(File file)[/b] -- 用于将 FileItem 对象中保存的主体内容保存到某个指定的文件中。如果 FileItem对象中的主体内容是保存在某个临时文件中,该方法顺利完成后,临时文件有可能会被清除。该方法也可将普通表单字段内容写入到一个文件中,但它主要用途是将上传的文件内容保存在本地文件系统中。
[b]public boolean isInMemory()[/b] -- 用来判断 FileItem 类对象封装的主体内容是存储在内存中,还是存储在临时文件中,如果存储在内存中则返回 true,否则返回false。
[b]public void delete()[/b] -- 用来清空 FileItem 类对象中存放的主体内容,如果主体内容被保存在临时文件中,delete 方法将删除该临时文件。

[b]上传文件的保存:[/b]

File uploadedFile = new File(...);
item.write(uploadedFile);


四)注意点:
对于fileupload,一共有3种上传文件的处理方式:
DiskFileUpload, ServletFileUpload, PortlerFileUpload
他们的区别是:
ServletFileUpload 最常用的类,大多情况我们就用它了。
DiskFileUpload 已被标记为Deprecated,由ServletFileUpload取代。
PortletFileUpload 需配合portlet的api一起使用(本人至今没用过 = =!)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值