みなさん、カスタムバリデータは作っていますか?
私の場合、実際に欲しいバリデータの大部分は
@Patternの正規表現とメッセージで表現できます。
しかし
@Pattern(regex="^[a-zA-Z]*$", message="国名は半角英字で入力してください")
public String getCountry() {
return this.country;
}
よりは
@Country
public String getCountry() {
return this.country;
}
のように書きたい(正規表現とメッセージの組を個々に定義して再利用)ので、
Hibernate Validatorの仕組み(@ValidatorClass)を使ってカスタムバリデータを作りました。
(参照: http://reyjexter.blogspot.com/2008/02/custom-hibernate-validator-that.html
)
この場合、アノテーション+バリデーション実装クラスが対になり、
実装クラスとしてPatternValidatorを使いまわせない(アノテーションがextendsできないのが痛い)ので、
同じような内容のバリデーション実装クラスをたくさん作るはめになります。
そこで正規表現を使うバリデーション実装クラスを共有するために
リフレクションを使って以下のようなクラスを書いてみましたが、
これがベストプラクティスなのか?というとイマイチ釈然としません。
こんな風にしているよ、などあればご意見お願いします。
# なんか大きな見落としがありそうな気が・・・
public class PatternValidatorSupport implements Validator<Annotation>,
Serializable {
private java.util.regex.Pattern pattern;
public void initialize(Annotation parameters) {
String regex;
int flags;
try {
// この辺もう少し安全にするための処理が必要か
regex =
(String)parameters.getClass().getDeclaredMethod("regex",
null).invoke(parameters, null);
flags =
(Integer)parameters.getClass().getDeclaredMethod("flags",
null).invoke(parameters, null);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (SecurityException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
pattern = java.util.regex.Pattern.compile(
regex,
flags
);
}
public boolean isValid(Object value) {
if ( value == null ) return true;
if ( !( value instanceof String ) ) return false;
String string = (String) value;
Matcher m = pattern.matcher( string );
return m.matches();
}
}
== PatternValidatorSupport を使うアノテーションの例 ==
@Documented
@ValidatorClass(PatternValidatorSupport.class)
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface Country{
/** regular expression */
String regex() default "^[a-zA-Z]*$";
/** regular expression processing flags */
int flags() default 0;
String message() default "国名は半角英字で入力してください";
}
_______________________________________________
Japan-jbug-seam mailing list
Japan-j...@lists.sourceforge.jp
http://lists.sourceforge.jp/mailman/listinfo/japan-jbug-seam