Apache Commons FileUpload 是 Java Web 文件上傳的經典解決方案。本文以版本 1.2 為基礎 (需搭配 Commons IO 1.3.2),透過四個漸進式範例,從最簡單的表單解析、多檔上傳、檔案大小限制,到 Servlet 整合部署,完整展示實務用法。
commons-fileupload-1.2.jar、commons-io-1.3.2.jar 放入 WEB-INF/libServletFileUpload:靜態工具類,解析 multipart/form-data 請求FileItemFactory / DiskFileItemFactory:建立 FileItem 實例,控制記憶體/磁碟臨界值FileItem:代表單一表單欄位 (一般欄位或檔案),提供 getName()、getString()、isFormField()、write(File) 等方法enctype="multipart/form-data")<form name="myform" action="demo1.jsp" method="post"
enctype="multipart/form-data">
Your name: <br>
<input type="text" name="name" size="15"><br>
File:<br>
<input type="file" name="myfile"><br>
<input type="submit" name="submit" value="Commit">
</form>
<%@ page import="org.apache.commons.fileupload.*" %>
<%@ page import="org.apache.commons.fileupload.servlet.*" %>
<%@ page import="org.apache.commons.fileupload.disk.*" %>
<%@ page import="java.util.*" %>
<%
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (isMultipart) {
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List<FileItem> items = upload.parseRequest(request);
Iterator<FileItem> itr = items.iterator();
while (itr.hasNext()) {
FileItem item = itr.next();
if (item.isFormField()) { // 一般表單欄位
String fieldName = item.getFieldName();
if ("name".equals(fieldName))
out.print("the field name is" + item.getString());
out.print("<br>");
} else { // 上傳檔案
out.print("the upload file name is" + item.getName());
out.print("<br>");
}
}
} else {
out.print("the enctype must be multipart/form-data");
}
%>
the field name isjeff
the upload file name isD:\C語言考試樣題\作業題.rar
myfile)<input type="file" name="myfile"><br>
<input type="file" name="myfile"><br>
<% String uploadPath = "D:\\temp"; %>
<%
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (isMultipart) {
try {
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List<FileItem> items = upload.parseRequest(request);
Iterator<FileItem> itr = items.iterator();
while (itr.hasNext()) {
FileItem item = itr.next();
String fileName = item.getName();
if (fileName != null) {
File fullFile = new File(item.getName());
File savedFile = new File(uploadPath, fullFile.getName());
item.write(savedFile); // 核心儲存方法
}
}
out.print("upload succeed");
} catch (Exception e) { e.printStackTrace(); }
} else {
out.println("the enctype must be multipart/form-data");
}
%>
結果:D:\temp 下出現兩個上傳檔案。
File uploadPath = new File("D:\\temp");
if (!uploadPath.exists()) uploadPath.mkdirs();
// 臨時緩衝區目錄 (超過 sizeThreshold 寫入磁碟)
File tempPathFile = new File("d:\\temp\\buffer\\");
if (!tempPathFile.exists()) tempPathFile.mkdirs();
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(4096); // 4KB 記憶體緩衝區
factory.setRepository(tempPathFile); // 緩衝區目錄
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setSizeMax(4194304); // 4MB 最大檔案限制
// 後續 parseRequest、iterate、write 同範例 2
關鍵參數說明:
setSizeThreshold:超過此大小 (bytes) 改用磁碟暫存,防止大檔吃光記憶體setRepository:磁碟暫存目錄setSizeMax:整體請求大小上限,超過拋出 SizeLimitExceededExceptionpackage com.zj.sample;
import java.io.File;
import java.io.IOException;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.commons.fileupload.*;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
public class Upload extends HttpServlet {
private String uploadPath = "D:\\temp";
private String tempPath = "d:\\temp\\buffer\\";
File tempPathFile;
public void init() throws ServletException {
new File(uploadPath).mkdirs();
tempPathFile = new File(tempPath);
tempPathFile.mkdirs();
}
@SuppressWarnings("unchecked")
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
try {
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(4096);
factory.setRepository(tempPathFile);
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setSizeMax(4194304); // 4MB
List<FileItem> items = upload.parseRequest(request);
Iterator<FileItem> i = items.iterator();
while (i.hasNext()) {
FileItem fi = i.next();
String fileName = fi.getName();
if (fileName != null) {
File fullFile = new File(fi.getName());
File savedFile = new File(uploadPath, fullFile.getName());
fi.write(savedFile);
}
}
System.out.print("upload succeed");
} catch (Exception e) {
e.printStackTrace(); // 實務應導向錯誤頁面
}
}
}
<form name="myform" action="fileupload" method="post"
enctype="multipart/form-data">
File:<br>
<input type="file" name="myfile"><br>
<input type="submit" name="submit" value="Commit">
</form>
<servlet>
<servlet-name>Upload</servlet-name>
<servlet-class>com.zj.sample.Upload</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Upload</servlet-name>
<url-pattern>/fileupload</url-pattern>
</servlet-mapping>
item.getName() 可能包含客戶端完整路徑 (IE 行為),建議用 new File(fileName).getName() 取純檔名ServletFileUpload.setHeaderEncoding("UTF-8") 或手動轉碼本文出自「子孑」部落格,轉載請保留出處:https://zhangjunhd.blog.51cto.com/113473/18331