CustomValidatorを作ってみた

とりあえず手っ取り早く独自のValidatorを作るには、
com.opensymphony.xwork2.validator.validators.FieldValidatorSupport
を拡張して以下のメソッドを実装すれば良いみたい。

public void validate(Object object) throws ValidationException;

で、この引数で渡ってくるObjectの値は、このValidatorが設定されているクラスの参照が渡ってきます。
例えば、
・HogeActionのexecuteメソッドに設定されているときはHogeActionのインスタンスへの参照
・UserというBeanのsetXxxメソッドに設定されているときはUserのインスタンスへの参照
が渡ってきます。
なので、パラメータでフィールド名さえ指定してあげれば、複数フィールドの関連をチェックするValidatorを作成可能です。
そこで試しに、ユーザ管理系でよくある「パスワード」と「パスワード確認入力」に同じ文字列が入力されたかチェックするValidatorを作ってみました。


入力チェッククラス

public class EqualsStringValidator extends FieldValidatorSupport {
	// 値を比較するフィールドの名前
	private String secondFieldName;

	public String getSecondFieldName() {
		return secondFieldName;
	}

	public void setSecondFieldName(String secondFieldName) {
		this.secondFieldName = secondFieldName;
	}

	public void validate(Object object) throws ValidationException {
		String fieldName = this.getFieldName();
		String secondFieldName = this.getSecondFieldName();

		Object value1 = this.getFieldValue(fieldName, object);
		Object value2 = this.getFieldValue(secondFieldName, object);

		if (!(value1 instanceof String) || !(value2 instanceof String)) {
			this.addFieldError(fieldName, object);
		}

		String s1 = (String) value1;
		String s2 = (String) value2;
		if (!s1.equals(s2)) {
			this.addFieldError(fieldName, object);
		}
	}

}


validators.xml(作成したValidatorを登録する為のファイル)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
        "-//OpenSymphony Group//XWork Validator Config 1.0//EN"
        "http://www.opensymphony.com/xwork/xwork-validator-config-1.0.dtd">
<validators>
    <validator name="equalsString" class="sample.validator.EqualsStringValidator"/>
</validators>


ActionFormへの設定
*パスワード(password)とパスワード確認入力(password2)をフィールドに持つ場合

	@CustomValidator(
			message="確認入力の値と一致しません",
			type="equalsString", 
			parameters={@ValidationParameter(name="secondFieldName", value="password2")})
	public void setPassword(String password) {
		this.password = password;
	}

CustomValidatorアノテーションのtype属性に、validators.xmlで定義した名前を指定します。
parameters属性に、各々のValidator独自のパラメータを指定します。


Struts2の入力チェックに関しては、単項目の文字列のチェックは元からある「regex validator」を使えばどうにでもなるし、
複数項目が絡むような複雑な入力チェックも、このように大した労力無く作成できそうかなぁ。