Struts 2 驗證框架基於 XWork,自定義驗證器只需繼承現有字段驗證器。本文以身份證號碼校驗(15/18 位、校驗碼算法)為例,完整演示開發流程。
解壓 xwork-2.0.4.jar,取出 com/opensymphony/xwork2/validator/validators/default.xml,放入專案根目錄並重命名為 validators.xml。框架啟動時優先讀取此檔,無則回退預設。
package org.siyn.commons.validators;
import com.opensymphony.xwork2.validator.ValidationException;
import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport;
public class CardIdFieldValidator extends FieldValidatorSupport {
public void validate(Object object) throws ValidationException {
String fieldName = getFieldName();
String value = getFieldValue(fieldName, object).toString();
if (value == null || value.length() == 0) return;
if (value.length() != 15 && value.length() != 18) {
addFieldError(fieldName, object);
return;
}
if (value.length() == 15) validate15CardId(value, object);
else validate18CardId(value, object);
}
/** 18 位身份證校驗(GB 11643-1999) */
private void validate18CardId(String value, Object object) {
String fieldName = getFieldName();
String body = value.substring(0, 17);
String checkCode = value.substring(17, 18).toLowerCase();
int[] coeff = {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
int sum = 0;
try {
for (int i = 0; i < 17; i++) {
sum += Integer.parseInt(body.substring(i, i+1)) * coeff[i];
}
} catch (NumberFormatException e) {
addFieldError(fieldName, object);
return;
}
String[] checkCodes = {"1","0","x","9","8","7","6","5","4","3","2"};
String expected = checkCodes[sum % 11];
if (!expected.equalsIgnoreCase(checkCode)) addFieldError(fieldName, object);
}
/** 15 位身份證僅做數字校驗 */
private void validate15CardId(String value, Object object) {
String fieldName = getFieldName();
for (int i = 0; i < 15; i++) {
if (!Character.isDigit(value.charAt(i))) {
addFieldError(fieldName, object);
break;
}
}
}
}
在 validators.xml 中添加:
<validator name="cardid" class="org.siyn.commons.validators.CardIdFieldValidator"/>
Action 類需有對應屬性(如 student.sfzh)。驗證檔命名規則:Action類名-validation.xml 或 Action類名-Action名-validation.xml。
<field name="student.sfzh">
<field-validator type="requiredstring" short-circuit="true">
<message>身份證號不能為空.</message>
</field-validator>
<field-validator type="cardid">
<message>身份證號格式不正確.</message>
</field-validator>
</field>
正常配置即可,驗證攔截器會自動調用。
FieldValidatorSupport,實現 validate(Object)。getFieldName()、getFieldValue() 獲取上下文。addFieldError(fieldName, object) 註冊。validators.xml 放在類路徑根目錄。