首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

深入剖析 WebWork 文件上傳機制:從請求攔截到臨時文件處理

     編輯:Java 相關知識

WebWork 文件上傳流程全景

在 WebWork(Struts 2 前身)中,文件上傳並非在 Action 執行時才開始,而是在請求進入 ServletDispatcher 的早期階段就已完成。整個流程可概括為四個關鍵步驟:

步驟 1:進入 ServletDispatcher.service()

請求首先到達 ServletDispatcher.service(HttpServletRequest, HttpServletResponse) 方法。此處調用 wrapRequest(request) 將原始請求包裝,以便後續處理多部分表單數據。

步驟 2:ServletDispatcher.wrapRequest() 判斷與包裝

在 wrapRequest 中,框架通過 MultiPartRequest.isMultiPart(request) 檢查是否為 multipart/form-data 請求。若是,則創建 MultiPartRequestWrapper 實例,傳入保存目錄(saveDir)與最大尺寸(maxSize)參數,並返回該包裝後的請求對象。

步驟 3:MultiPartRequestWrapper 構造器——解析器選擇與實例化

構造器內部邏輯分為兩階段:

  1. 讀取配置:從 webwork.properties 獲取 webwork.multipart.parser 屬性。若未配置,預設使用 PellMultiPartRequest 並記錄警告;也支援舊式簡寫 pell、cos、jakarta 分別映射到對應實現類。
  2. 反射實例化:通過 Class.forName() 載入解析器類,驗證其繼承自 MultiPartRequest,然後調用構造器 (HttpServletRequest, String, int) 創建實例,賦值給內部 multi 字段。

步驟 4:具體解析器執行——以 JakartaMultiPartRequest 為例

若配置使用 Jakarta 解析器,則進入 JakartaMultiPartRequest 構造器:

  • 創建 DiskFileUpload,設置 setSizeThreshold(0) 強制所有內容寫入磁盤臨時文件(因 WebWork API 缺乏流式處理能力)。
  • 調用 upload.parseRequest(servletRequest) 解析請求,將每個表單字段與上傳文件均生成獨立臨時文件(如 upload_00000017.tmp)。

解析完成後,控制權返回 ServletDispatcher.wrapRequest,隨後進入 serviceAction 開啟 Action 與攔截器棧調用。

關鍵特性與潛在問題

1. 文件上傳時機早於 Action 執行

當 Action 棧開始執行時,文件已全部寫入臨時目錄。開發者在 Action 或攔截器中通過 MultiPartRequestWrapper.getFiles("fieldName") 即可獲取 File 數組進行後續業務處理(如複製至永久路徑)。

2. 臨時文件命名難以追蹤,進度監控困難

臨時文件採用 upload_XXXXXXXX.tmp 格式,序號由上傳順序決定。高併發場景下,無法預知某用戶上傳文件對應的臨時文件名,導致實現上傳進度條極其困難(除非修改源碼或擴展框架)。

3. 雙重拷貝機制的性能考量

WebWork 採用「兩次拷貝」:第一次從請求輸入流寫入臨時文件,第二次從臨時文件複製到目標路徑。這在簡化 API 設計的同時,帶來了額外 I/O 開銷。對於大文件場景,建議評估是否直接使用流式處理庫(如 Apache Commons FileUpload 的 Streaming API)繞過臨時文件。

4. 臨時文件清理機制不確定

非上傳文件的臨時文件(如普通表單字段)會在某個時刻被刪除,但具體清理時間點不固定(有時極早、有時極晚、甚至遺留),推測可能有守護線程定期掃描。生產環境需監控臨時目錄磁盤佔用,必要時編寫定時清理任務。

最佳實踐建議

  • 配置解析器:明確在 webwork.properties 中指定 webwork.multipart.parser=jakarta(或 cos),避免預設 Pell 解析器的已知缺陷。
  • 設置合理閾值:通過 webwork.multipart.maxSize 限制上傳大小,防止惡意佔用磁盤。
  • 及時處理臨時文件:在 Action 中拿到 File 對象後,儘快移動至業務目錄並清理引用,減少臨時文件殘留風險。
  • 進度監控替代方案:若需上傳進度,考慮引入前端分片上傳(如 Resumable.js、Uppy)或使用支援進度監聽的獨立上傳服務,而非依賴 WebWork 內建機制。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved