Apache Commons Validator 成為 Struts 內建驗證框架,透過 XML 宣告式配置替代硬編碼 validate() 方法,實現驗證邏輯與業務代碼分離。本文系統講解 validator-rules.xml、validation.xml 核心配置、ActionForm 整合、客戶端 JavaScript 生成及擴展要點。
commons-validator.jar:驗證規則引擎、內建驗證器(required、email、mask 等)jakarta-oro.jar:正則表達式引擎(Validator 1.4+ 已內建 java.util.regex,舊版需此包)| 文件 | 職責 | 修改頻率 |
|---|---|---|
validator-rules.xml | 定義全域驗證規則(validator 實現類、錯誤訊息鍵、JS 函數) | 低(升級框架時更新) |
validation.xml | 針對具體 Form 組合規則、配置參數、錯誤訊息 | 高(隨業務變更) |
最佳實踐:勿直接修改 validator-rules.xml,需擴展規則時在 validation.xml <global> 區定義常量或自訂 validator。
<form-validation>
<global>
<constant>
<constant-name>pwdRegex</constant-name>
<constant-value>^(?=.*[a-z])(?=.*\d)[\w]{6,20}$</constant-value>
</constant>
</global>
<formset>
<form name="loginForm">
<!-- 用戶名:必填 -->
<field property="username" depends="required">
<arg0 key="label.username" />
</field>
<!-- 密碼:必填 + 長度 + 正則 -->
<field property="password" depends="required,minlength,maxlength,mask">
<arg0 key="label.password" />
<arg1 name="minlength" key="${var:minlength}" resource="false" />
<arg2 name="maxlength" key="${var:maxlength}" resource="false" />
<var>
<var-name>mask</var-name>
<var-value>${pwdRegex}</var-value>
</var>
<var><var-name>minlength</var-name><var-value>6</var-value></var>
<var><var-name>maxlength</var-name><var-value>20</var-value></var>
</field>
<!-- 郵箱:內建 email 規則 -->
<field property="email" depends="required,email">
<arg0 key="label.email" />
</field>
</form>
</formset>
</form-validation>
depends:逗號分隔的規則名,按順序執行,任一失敗即停止arg0..argN:錯誤訊息參數,key 可引用資源包,resource="false" 直接使用字面值var:向規則傳遞參數(如 minlength、mask 正則)| Form 類別 | 對應 validation.xml form name | 適用場景 |
|---|---|---|
ValidatorForm | <form-bean name="loginForm"> 的 name | 傳統 ActionForm,單一驗證邏輯 |
ValidatorActionForm | <action path="/login"> 的 path (去掉 /) | 同一 Form 對應多 Action,需差異化驗證 |
DynaValidatorForm | 同 ValidatorForm | 動態屬性 Form,無需編寫 Java 類 |
DynaValidatorActionForm | 同 ValidatorActionForm | 動態屬性 + 多 Action 差異驗證 |
<formset>
<!-- ValidatorActionForm 模式:按 action path 區分 -->
<form name="login"> <!-- 對應 /login.do -->
<field property="password" depends="required,mask">...</field>
</form>
<form name="cancel"> <!-- 對應 /cancel.do -->
<!-- 取消無需驗證密碼 -->
</form>
</formset>
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property property="pathnames"
value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml" />
<!-- 可選:自定義訊息資源 -->
<set-property property="resourcePath" value="ApplicationResources" />
</plug-in>
validator-rules.xml 中每個 <validator> 內嵌 <javascript> 定義 JS 函數<html:javascript formName="loginForm" /> 自動生成 validateLoginForm(form)<html:form action="/login.do" onsubmit="return validateLoginForm(this);">驗證失敗時彈出警示框,阻止表單提交,減輕伺服器壓力。
public class ChineseMobileValidator implements Validator {
private static final Pattern MOBILE = Pattern.compile("^1[3-9]\d{9}$");
public boolean validate(Object bean, ValidatorAction va, Field field,
ActionMessages errors, ActionForm form,
HttpServletRequest request) {
String value = ValidatorUtil.getValueAsString(bean, field.getProperty());
return value == null || MOBILE.matcher(value).matches();
}
}
<global>
<validator name="chineseMobile"
classname="com.myapp.validator.ChineseMobileValidator"
method="validate"
methodParams="java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionMessages,
org.apache.struts.action.ActionForm,
javax.servlet.http.HttpServletRequest"
msg="errors.chineseMobile" />
</global>
<field property="mobile" depends="required,chineseMobile">
<arg0 key="label.mobile" />
</field>
field property 必須與 Form Bean 的 getter/setter 對應(如 userName 對應 getUserName())property="address.city",需確保 getAddress() 不返回 nullarg0 key="label.username" 需在 ApplicationResources.properties 定義validator-rules.xml 含 <javascript>,且 JSP 引入 <html:javascript> 位置正確struts-config.xml 需配置 <form-property> 定義屬性類型Validator 框架以 XML 宣告式配置大幅減少驗證樣板代碼,支援伺服端/客戶端雙重驗證,靈活的 Form/Action 級區分滿足複雜業務場景。掌握 validation.xml 結構、四類 Form 選型、自訂 Validator 擴展,即可在 Struts 專案中構建健壯、可維護的驗證體系。