Struts 1 專案隨著功能增長,易陷入「Action 類別爆炸」與「ActionForm 類別爆炸」雙重困境。本文系統介紹三大內建機制:DispatchAction 合併同業務 Action、DynaActionForm 動態減少 Form Bean 類別、DynaValidatorForm 整合驗證框架,並給出完整配置步驟與最佳實踐。
單一 Action 類別包含多個業務方法(insert()、update()、delete()...),透過請求參數指定執行哪個方法。
public class UserDispatchAction extends DispatchAction {
public ActionForward insert(ActionMapping mapping, ActionForm form,
HttpServletRequest req, HttpServletResponse resp) {
// 新增邏輯
return mapping.findForward("success");
}
public ActionForward update(...) { ... }
public ActionForward delete(...) { ... }
public ActionForward query(...) { ... }
}
<html:form action="/userDispatch">
<html:hidden property="method" value="insert"/> <-- 或 update/delete/query -->
... 其他欄位 ...
</html:form>
<action path="/userDispatch"
type="com.example.UserDispatchAction"
parameter="method" <-- 對應隱藏域名稱 -->
name="userForm"
scope="request"
validate="true">
<forward name="success" path="/userList.do"/>
</action>
提交表單時,DispatchAction 會根據 method 參數值動態調用對應方法。
無需編寫 Java 類別,直接在 struts-config.xml 宣告屬性名稱與型別,框架自動建立動態 Form Bean 實例。
<form-beans>
<form-bean name="userForm"
type="org.apache.struts.action.DynaActionForm">
<form-property name="userId" type="java.lang.Long"/>
<form-property name="username" type="java.lang.String"/>
<form-property name="email" type="java.lang.String"/>
<form-property name="age" type="java.lang.Integer"/>
</form-bean>
</form-beans>
Action 中取值:
DynaActionForm form = (DynaActionForm) actionForm;
Long userId = (Long) form.get("userId");
String username = (String) form.get("username");
<form-bean name="userForm"
type="org.apache.struts.validator.DynaValidatorForm">
<form-property name="userId" type="java.lang.Long"/>
<form-property name="username" type="java.lang.String"/>
<form-property name="email" type="java.lang.String"/>
</form-bean>
<form-validation>
<formset>
<form name="userForm">
<field property="username" depends="required,minlength,maxlength">
<arg key="user.username" resource="true"/>
<arg key="${var:minlength}" resource="false" position="1"/>
<arg key="${var:maxlength}" resource="false" position="2"/>
<var><var-name>minlength</var-name><var-value>2</var-value></var>
<var><var-name>maxlength</var-name><var-value>20</var-value></var>
</field>
<field property="email" depends="required,email">
<arg key="user.email" resource="true"/>
</field>
</form>
</formset>
</form-validation>
user.username=用戶名
user.email=電子郵件
errors.required={0} 不能為空
errors.minlength={0} 長度不能少於 {1} 字元
errors.maxlength={0} 長度不能超過 {1} 字元
errors.email={0} 格式不正確
<action path="/userDispatch"
...
validate="true" <-- 關鍵:啟用驗證 -->
input="/userForm.jsp"> <-- 驗證失敗返回頁面 -->
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property property="pathnames"
value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>
</plug-in>
| 問題 | 方案 | 適用場景 | 注意事項 |
|---|---|---|---|
| Action 類別過多 | DispatchAction | 同一業務實體的 CRUD 操作 | 方法簽名必須固定;避免濫用導致單一類別過大 |
| ActionForm 類別過多 | DynaActionForm | 簡單資料傳輸、無複雜邏輯的表單 | 型別安全性較弱;複雜驗證/轉換仍建議寫實體類 |
| 動態 Form 需驗證 | DynaValidatorForm + Validator | 需聲明式驗證的動態表單 | 驗證規則集中在 XML,維護方便但調試較難 |
DispatchAction、DynaActionForm、DynaValidatorForm 是 Struts 1 時代應對類別爆炸的三板斧。合理運用可大幅減少樣板代碼,將開發焦點集中在業務邏輯。但隨著框架演進,現代 MVC 框架已從根本上解決此類問題,建議新專案直接採用現代化技術棧。