在上一篇《Struts 2 教程 4:使用 validate 方法驗證數據》中,我們學會了在 Action 中覆寫 validate() 方法進行驗證。但隨著業務增長,驗證邏輯與業務代碼混雜,維護困難、難以複用。Struts 2 提供了基於 XML 配置的 Validation 框架,將驗證規則外部化,實現關注點分離。本文將通過完整實例,詳解服務端驗證、客戶端驗證及巢狀屬性驗證的實作步驟。
package action;
import com.opensymphony.xwork2.ActionSupport;
public class NewValidateAction extends ActionSupport {
private String msg; // 必填
private int age; // 13~20 之間
// getter / setter 省略
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"https://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="demo" extends="struts-default" namespace="/test">
<action name="new_validate" class="action.NewValidateAction">
<result name="input">/validate_form.jsp</result>
<result name="success">/validate_form.jsp</result>
</action>
</package>
</struts>
注意:namespace="/test" 需在 JSP 的 <s:form> 中分開寫 action 與 namespace,不可合寫為 /test/new_validate。
檔案命名規則:<ActionClassName>-validation.xml 或 <ActionClassName>-<ActionAliasName>-validation.xml,放置於 Action 類同目錄下。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
"https://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
<validators>
<field name="msg">
<field-validator type="requiredstring">
<message>請輸入信息</message>
</field-validator>
</field>
<field name="age">
<field-validator type="int">
<param name="min">13</param>
<param name="max">20</param>
<message>必須在 13 至 20 之間</message>
</field-validator>
</field>
</validators>
常用驗證器:requiredstring(非空字串)、int/double(數值範圍)、email、url、regex 等。完整列表請參閱 官方文檔。
<%@ page language="java" pageEncoding="GBK"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head><title>驗證數據</title>
<link rel="stylesheet" type="text/css" href="<s:url value='/styles/styles.css'/>">
</head>
<body>
<s:form action="new_validate" namespace="/test">
<s:textfield name="msg" label="姓名" />
<s:textfield name="age" label="年齡"/>
<s:submit/>
</s:form>
</body>
</html>
錯誤樣式 styles.css:
.label {font-style:italic;}
.errorLabel {font-style:italic; color:red;}
.errorMessage {font-weight:bold; color:red;}
只需在 <s:form> 加入 validate="true":
<s:form validate="true" action="new_validate" namespace="/test"> ... </s:form>
框架自動生成 JavaScript,在瀏覽器端完成同規則驗證,無需額外配置。
當 Action 包含複雜類型屬性(如 User user)時,需驗證其內部字段。
package data;
public class User {
private String name;
private int age;
// getter/setter 省略
}
private User user;
// getter/setter 省略
<field name="user">
<field-validator type="visitor">
<param name="context">abc</param>
<param name="appendPrefix">true</param>
<message>User:</message>
</field-validator>
</field>
context:子驗證文件名的一部分,如 User-abc-validation.xml。appendPrefix=true:表單字段名需帶前綴 user.name、user.age。<validators>
<field name="name">
<field-validator type="requiredstring">
<message>請輸入 name</message>
</field-validator>
</field>
<field name="age">
<field-validator type="int">
<param name="min">5</param>
<param name="max">20</param>
<message>必須在 5 至 20 之間</message>
</field-validator>
</field>
</validators>
<s:textfield name="user.name" label="姓名1" />
<s:textfield name="user.age" label="年齡1"/>
測試發現:Visitor 驗證器目前不支援客戶端驗證,但 Action 其他屬性仍可使用客戶端驗證。
validate="true" 即可開啟。visitor 驗證器,配合 context 與 appendPrefix 實現多層級驗證。