首先要处理上传文件的请求,必须满足两个条件:
- request遵守
post
方法 - form编码格式必须为
multipart/form-data
- 参考如下:
<form method="POST" enctype="multipart/form-data" action="...">
<input type="file" name="upfile"><br/>
<input type="submit" value="上传文件">
</form>
准备条件:
- 文件上传依赖
Commons IO
包,所以你需要导入jar
包或者在pom
文件中声明该依赖 - 参考如下:(jar包可以在maven仓库下载)
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
实现原理:
- 在一次文件上传请求中,提交表单的每一个输入项都是一个
item
,这些item
组成一个列表,其中,每一个item
都实现了FileItem
接口 -
FileItemFactory
负责存储每一个item
到你的磁盘中
操作步骤:
1. 解析请求
- 判断是否为文件上传请求
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
- 相关配置
// 创建产生item的工厂
DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
// 设置存放临时文件的目录(大文件)
File repository = (File) getServletContext().getAttribute("javax.servlet.context.tempdir");
// 设置阈值,区分大文件还是小文件
diskFileItemFactory.setSizeThreshold(1024 * 1024 * 1024 * 1024);
// 设置临时文件仓库
diskFileItemFactory.setRepository(repository);
// 创建文件上传句柄
ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
// 解析请求,生成items列表,待后续处理
List<FileItem> fileItems = servletFileUpload.parseRequest(req);
2. 处理item
列表
没错,就是简单的遍历处理:
Iterator<FileItem> iter = items.iterator();
while (iter.hasNext()) {
FileItem item = iter.next();
if (item.isFormField()) {
processFormField(item);
} else {
processUploadedFile(item);
}
}
其中具体的if else处理依据你的业务逻辑而定,你可以获得每一个item的属性并输出到控制台,可以生成文件字节流,写入文件内容到目录中,具体怎么处理看这个链接
资源清理
为了节省服务器资源,对于存放在临时目录下的大文件(超过我们设置的阈值的
),我们可以设置处理器定时去清楚他们。QQ群里面的大文件,一段时间后就会被自动清除就是这个道理。
简单配置即可:
<web-app>
...
<listener>
<listener-class>
org.apache.commons.fileupload.servlet.FileCleanerCleanup
</listener-class>
</listener>
...
</web-app>