首先要處理上傳文件的請求,必須滿足兩個條件:
- 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>