WebWork 文件上傳看似簡單,實則涉及請求包裝、解析器策略、臨時檔案管理等核心機制。本文從原始碼層面完整追蹤上傳流程,揭示兩次拷貝、臨時檔案命名難題、進度追蹤困境等關鍵特性。
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException {
request = wrapRequest(request); // 關鍵:包裝請求
// ...
}
protected HttpServletRequest wrapRequest(HttpServletRequest request)
throws IOException {
if (MultiPartRequest.isMultiPart(request)) {
request = new MultiPartRequestWrapper(request, getSaveDir(), getMaxSize());
}
return request;
}
public MultiPartRequestWrapper(HttpServletRequest request, String saveDir, int maxSize)
throws IOException {
// 3.1 從 webwork.properties 讀取解析器類別
String parser = Configuration.getString("webwork.multipart.parser");
if (parser.equals("")) {
parser = "com.opensymphony.webwork.dispatcher.multipart.PellMultiPartRequest";
} else if (parser.equals("pell")) { /* ... */ }
else if (parser.equals("cos")) { /* ... */ }
else if (parser.equals("jakarta")) { /* ... */ }
// 3.2 反射實例化解析器
Class baseClazz = MultiPartRequest.class;
Class clazz = Class.forName(parser);
Constructor ctor = clazz.getDeclaredConstructor(
HttpServletRequest.class, String.class, int.class);
Object[] parms = new Object[] { request, saveDir, new Integer(maxSize) };
multi = (MultiPartRequest) ctor.newInstance(parms);
}
支援三種解析器:Pell(預設)、COS、Jakarta Commons FileUpload。
public JakartaMultiPartRequest(HttpServletRequest servletRequest, String saveDir, int maxSize)
throws IOException {
DiskFileUpload upload = new DiskFileUpload();
upload.setSizeThreshold(0); // 強制所有上傳寫入磁碟(含表單欄位)
upload.setSizeMax(maxSize);
if (saveDir != null) upload.setRepositoryPath(saveDir);
List items = upload.parseRequest(servletRequest); // 生成臨時檔案
// upload_00000017.tmp, upload_00000018.tmp ...
}
關鍵發現:setSizeThreshold(0) 導致所有請求參數(含一般表單欄位)皆生成臨時檔案,檔名格式 upload_XXXXXXXX.tmp 難以追蹤對應關係。
wrapRequest,進入 serviceAction 啟動 Action 與攔截器堆疊MultiPartRequestWrapper 存取上傳檔案:MultiPartRequestWrapper wrapper = (MultiPartRequestWrapper) req;
File doc = wrapper.getFiles("doc")[0];
進入 Action 堆疊時檔案已寫入臨時目錄。若需上傳進度顯示,WebWork 原生機制無法支援(臨時檔名不可預測、無進度回呼)。
效能開銷明顯,大檔案場景需考慮串流式處理替代方案。
MultiPartRequest 解析器,整合進度監聽器(如 Apache Commons FileUpload ProgressListener)MultiPartRequestWrapper 覆寫解析邏輯,採用串流直寫目標路徑避免二次拷貝@MultipartConfig 或 Spring MVC MultipartResolver,原生支援進度、串流、配置簡化WebWork 文件上傳機制以策略模式支援多解析器、請求包裝器隔離解析細節,設計精巧但受限於臨時檔案架構,難以滿足現代進度顯示、大檔案高效傳輸需求。理解其內部流程有助於舊系統維護與遷移決策,新專案建議採用現代標準 API。