文件上傳是 Web 開發中極為常見的功能。本文將詳細介紹如何使用 Apache Commons FileUpload 元件,結合 Servlet 與 JSP 實現一個基礎的文件上傳示例。文章涵蓋所需依賴、核心 Servlet 代碼、前端表單編寫以及關鍵配置細節,幫助你快速掌握文件上傳的核心流程。
在開始編碼前,請確保專案類路徑下已包含以下兩個核心庫:
若使用 Maven 管理專案,可直接在 pom.xml 中添加對應依賴坐標。
我們編寫一個繼承 HttpServlet 的 UploadServlet,專門處理 POST 請求。關鍵步驟包括:配置磁碟工廠、設置上傳限制、解析請求、遍歷文件項並保存。
package web.servlet;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
@WebServlet("/UploadServlet")
public class UploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
// 上傳文件最終存放目錄
private String uploadPath = "D:\\temp";
// 臨時緩衝區目錄
private String tempPath = "D:\\temp\\buffer\\";
private File tempPathFile;
@Override
public void init() throws ServletException {
// 初始化時自動創建目錄
File uploadDir = new File(uploadPath);
if (!uploadDir.exists()) uploadDir.mkdirs();
tempPathFile = new File(tempPath);
if (!tempPathFile.exists()) tempPathFile.mkdirs();
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
try {
// 1. 創建磁碟文件項工廠
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(4096); // 緩衝區大小 4KB
factory.setRepository(tempPathFile); // 設置臨時文件目錄
// 2. 創建文件上傳處理器
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setSizeMax(4194304); // 設置最大上傳 4MB
// 3. 解析請求,獲取所有文件項
List<FileItem> items = upload.parseRequest(request);
Iterator<FileItem> iter = items.iterator();
while (iter.hasNext()) {
FileItem item = iter.next();
String fileName = item.getName();
if (fileName != null && !fileName.isEmpty()) {
// 處理路徑分隔符差異,僅取文件名
File fullFile = new File(fileName);
File savedFile = new File(uploadPath, fullFile.getName());
item.write(savedFile); // 寫入磁碟
}
}
response.getWriter().write("upload succeed");
} catch (Exception e) {
e.printStackTrace();
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "上傳失敗: " + e.getMessage());
}
}
}
setSizeThreshold 定義內存緩衝閾值,超過則寫入臨時目錄(setRepository)。setSizeMax 限制總請求大小,防止惡意大文件攻擊。upload.parseRequest(request):將 multipart/form-data 請求解析為 FileItem 列表,每個項代表一個表單字段或文件。item.write(file):將文件內容寫入目標路徑,自動處理內存/臨時文件切換。前端關鍵在於 form 標籤必須設置 enctype="multipart/form-data",且 method="post"。action 指向 Servlet 映射路徑。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>文件上傳示例</title>
</head>
<body>
<h3>文件上傳測試</h3>
<form name="uploadForm" action="UploadServlet" method="post" enctype="multipart/form-data">
選擇文件: <br>
<input type="file" name="myfile"><br><br>
<input type="submit" value="上傳">
</form>
</body>
</html>
\\,Linux/Mac 使用 /,建議用 File.separator 或 Paths.get() 跨平台兼容。request.getPart() 實現無第三方依賴上傳。Apache Commons FileUpload 提供了成熟、靈活的文件上傳解決方案。通過 DiskFileItemFactory 控制緩衝策略,ServletFileUpload 解析請求,配合合理的異常處理與目錄管理,即可構建穩健的上傳功能。本文示例為最基礎實現,實際項目中建議封裝為通用工具類,並整合 Spring MVC 的 MultipartResolver 簡化開發。