WebWork(現 Struts 2 前身)以簡潔、靈活、強大的 Command 模式框架著稱,徹底脫離 Web 層,致力於組件化與程式碼重用。許多開發者熟知其核心優勢,卻鮮少發現它在文件上傳上的極致優雅:配合 OGNL 資料綁定與內建攔截器,Action 完全不需感知任何 Web 細節,即可像操作普通 Java 物件一樣處理上傳檔案。本文將帶你從原理到實作,輕鬆掌握 WebWork 文件上傳的最佳實踐。
傳統 Servlet 開發需手動呼叫 request.getParameter()、撰寫 Setter、轉換型別,甚至準備 DTO/FormBean。WebWork 的 OGNL 機制自動完成:
user.address.city)將此機制延伸至文件上傳,Action 僅需定義 java.io.File 型別屬性及 Setter,即可直接操作檔案物件,完全不需處理 multipart/form-data 解析細節。
WebWork 2.1.5 版本起,com.opensymphony.webwork.interceptor.FileUploadInterceptor 正式納入核心發布版。該攔截器自動:
multipart/form-data 請求File 物件並注入 Action 同名屬性屬性名FileName)與 Content-Type(屬性名ContentType)public class UploadAction extends ActionSupport {
private File uploadFile; // 上傳檔案
private String uploadFileFileName; // 原始檔名
private String uploadFileContentType; // MIME 類型
// Getter/Setter 省略
public String execute() {
// 直接操作 uploadFile 物件:複製、移動、解析...
File dest = new File("/data/upload", uploadFileFileName);
FileUtils.copyFile(uploadFile, dest);
return SUCCESS;
}
}

<form action="upload.action" method="post" enctype="multipart/form-data">
<input type="file" name="uploadFile" />
<input type="submit" value="上傳" />
</form>

關鍵點: input name="uploadFile" 必須與 Action 中 File uploadFile 屬性名完全一致,框架自動完成其餘綁定工作。
在 xwork.xml 或 struts.xml 中確保 Action 使用的攔截器堆疊包含 fileUpload:
<interceptor-stack name="defaultStack">
<!-- 其他攔截器 -->
<interceptor-ref name="fileUpload"/>
<!-- 其他攔截器 -->
</interceptor-stack>
<action name="upload" class="com.example.UploadAction">
<interceptor-ref name="defaultStack"/>
<result name="success">/success.jsp</result>
</action>
預設堆疊 defaultStack 已內建 fileUpload,若自訂堆疊請務必加入。
可透過 Action 實作 ValidationAware 或在攔截器參數中設定:
<interceptor-ref name="fileUpload">
<param name="maximumSize">2097152</param> <!-- 2MB -->
<param name="allowedTypes">image/jpeg,image/png,application/pdf</param>
</interceptor-ref>
驗證失敗時,攔截器會將錯誤訊息加入 ActionErrors,前端可用 <s:fielderror /> 顯示。
List<File> uploadFiles 及對應 uploadFilesFileName、uploadFilesContentType 列表即可支援多檔同時上傳。WebWork 的文件上傳設計完美詮釋了「關注點分離」:Action 專注業務邏輯,框架負責 Web 協議細節。配合 OGNL 強大的資料綁定,開發者告別繁瑣的 request.getInputStream() 解析,擁抱乾淨、可測試、可重用的程式碼風格。下次專案需求文件上傳時,不妨嘗試這種「零配置、強型別」的優雅寫法,體驗框架為你承擔底層複雜度的暢快。