Struts2 內建 XWork Validator 框架,支援三種驗證方式:validate() 方法、XML 配置、註解。本文以用戶註冊場景為例,完整演示三種方式的配置、代碼、優缺點對比,並解決 XML 正則驗證參數名錯誤的遺留問題。
public class User {
private String name; private int age; private String email; private Date birthDay;
// getter/setter 省略
}
public class ValidatorAction extends ActionSupport {
private User user; private List userList = new ArrayList<>();
@Override public void validate() {
if (user != null) {
if (!regex(user.getName(), "^[A-Za-z][A-Za-z0-9_-]+$"))
addFieldError("user.name", "用戶名格式錯誤");
if (!regex(String.valueOf(user.getAge()), "(?:[1-9][0-9]?|1[01][0-9]|120)"))
addFieldError("user.age", "年齡 0-120");
if (outOfRange(user.getBirthDay(), "1900-01-01", "2017-01-01"))
addFieldError("user.birthDay", "生日範圍錯誤");
if (!regex(user.getEmail(), "^[a-zA-Z_][0-9]*@([a-zA-Z0-9-]+\\.)+[a-zA-Z-]+$"))
addFieldError("user.email", "郵箱格式錯誤");
}
}
public String addUser() { userList.add(user); return SUCCESS; }
// regex/outOfRange 工具方法省略
}
struts.xml 需配置 `
方法名規則:validate + Action方法名首字母大寫,如 validateAddUser()。配置 `
<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.3//EN"
"https://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
<validators>
<field name="user.name">
<field-validator type="regex">
<param name="regexExpression"><![CDATA[^[A-Za-z][A-Za-z0-9_-]+$]]></param>
<message>用戶名格式錯誤</message>
</field-validator>
</field>
<field name="user.email">
<field-validator type="email"><message>郵箱格式錯誤</message></field-validator>
</field>
<field name="user.age">
<field-validator type="int">
<param name="min">1</param><param name="max">120</param>
<message>年齡 1-120</message>
</field-validator>
</field>
<field name="user.birthDay">
<field-validator type="date" short-circuit="true">
<param name="min">1900-01-01</param><param name="max">2050-02-21</param>
<message>生日在 ${min} 到 ${max} 之間</message>
</field-validator>
</field>
</validators>
**關鍵修正**:正則驗證參數名為 regexExpression,而非 expression 或 regex(官方文檔易混淆,源碼確認為 regexExpression)。
<struts:form action="regist" method="post" validate="true">
<struts:textfield name="user.name" label="用戶名"/>
<struts:textfield name="user.age" label="年齡"/>
<struts:textfield name="user.birthDay" label="生日"/>
<struts:textfield name="user.email" label="郵箱"/>
<struts:submit value="註冊"/>
</struts:form>
@Validations(
emails = @EmailValidator(fieldName="user.email", message="郵箱格式錯誤"),
conversionErrorFields = @ConversionErrorFieldValidator(fieldName="user.age", message="年齡轉換錯誤"),
intRangeFields = @IntRangeFieldValidator(fieldName="user.age", min="0", max="120", message="年齡 0-120"),
dateRangeFields = @DateRangeFieldValidator(fieldName="user.birthDay", min="1900-01-01", max="2017-03-30", message="日期錯誤"),
regexFields = @RegexFieldValidator(regexExpression="^[A-Za-z][A-Za-z0-9_-]+$", fieldName="user.name", message="用戶名格式錯誤")
)
public String addUser() { ... }
支援的驗證器:requiredString/required/intRange/dateRange/email/url/stringLength/regex/expression/visitor/custom 等。
| 維度 | validate() | XML | 註解 |
|---|---|---|---|
| 耦合度 | 高(邏輯在 Action 中) | 低(獨立文件) | 中(類/方法上) |
| 復用性 | 差 | 高(可被多 Action 引用) | 中 |
| 類型安全 | 編譯期 | 運行期 | 編譯期 |
| 國際化 | 手動 | 支援 key | 支援 key |
| 適用場景 | 簡單、強業務邏輯 | 複雜、跨 Action 復用 | 中小型、偏好代碼配置 |
regexExpression,已在本文修正Struts2 雖非主流,但其驗證框架設計思想(聲明式、可擴展、多格式)仍具參考價值。