1. 概述
《Apache Commons File Upload 庫》幫助我們使用 multipart/form-data 內容類型,通過 HTTP 協議上傳大型文件。
在本快速教程中,我們將探討如何將其與 Spring 集成。
2. Maven 依賴
要使用該庫,我們需要 commons-fileupload2-jakarta 構件:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-fileupload2-jakarta</artifactId>
<version>2.0.0-M1</version>
</dependency>最新版本可以在 Maven Central 找到。
3. 一次性傳輸所有數據
為了演示目的,我們將創建一個 控制器,該控制器將處理包含文件負載的請求:
@PostMapping("/upload")
public String handleUpload(HttpServletRequest request) throws Exception {
boolean isMultipart = JakartaServletFileUpload.isMultipartContent(request);
DiskFileItemFactory factory = DiskFileItemFactory.builder().get();
JakartaServletFileUpload upload = new JakartaServletFileUpload(factory);
List items = upload.parseRequest(request);
Iterator iter = items.iterator();
while (iter.hasNext()) {
FileItem item = iter.next();
if (!item.isFormField()) {
try (
InputStream uploadedStream = item.getInputStream();
OutputStream out = new FileOutputStream("file.mov");) {
IOUtils.copy(uploadedStream, out);
}
}
}
return "success!";
}
在開始之前,我們需要檢查請求是否包含多部分內容,使用 ServletFileUpload 類中的 isMultipartContent 方法。
默認情況下,Spring 提供了 MultipartResolver,我們需要禁用它才能使用該庫。否則,它會在請求內容被我們的 Controller 處理之前讀取請求內容。
可以通過在我們的 application.properties 文件中包含以下配置來實現:
spring.http.multipart.enabled=false該庫提供了一個 DiskFileItemFactory 類,它負責文件的保存和清理配置。我們可以使用 DiskFileItemFactory.builder() 方法創建它。由於直接構造函數是私有的,因此必須使用 Builder 方法。
現在我們可以繼續到實際的文件處理。
首先,我們創建我們的 JakartaServletFileUpload,通過包含我們之前創建的工廠;然後我們繼續解析請求並生成一個 FileItem 列表,這些是庫中表單字段的主要抽象。
如果已知這不是一個標準的表單字段,那麼我們繼續提取 InputStream 並調用 IOUtils 中的有用複製方法(有關更多選項,請參閲此教程)。
現在我們已經將文件存儲在必要的文件夾中。這通常是處理這種情況的一種更方便的方式,因為它允許輕鬆訪問文件,但效率(時間和內存)可能不是最優的。
在下一部分中,我們將查看流式 API。
4. 實時 API
實時 API 易於使用,通過避免將數據複製到臨時位置,使其成為處理大型文件的一種便捷方式:
JakartaServletFileUpload upload = new JakartaServletFileUpload();
FileItemInputIterator iterStream = upload.getItemIterator(request);
while (iterStream.hasNext()) {
FileItemInput item = iterStream.next();
String name = item.getFieldName();
InputStream stream = item.getInputStream();
if (!item.isFormField()) {
// Process the InputStream
} else {
String formFieldValue = IOUtils.toString(stream, StandardCharsets.UTF_8);
}
}
我們可以從之前的代碼片段中看到,我們不再包含 DiskFileItemFactory。這是因為,當使用流式 API 時,我們不需要它。
接下來,為了處理字段,該庫提供了一個 FileItemInputIterator,它在通過 next 方法從請求中提取它們之前不會讀取任何內容。
最後,我們可以看到如何獲取其他表單字段的值。
結論
在本文中,我們回顧瞭如何使用 Apache Commons File Upload 庫與 Spring 結合,上傳和處理大型文件。