Hibernate Validatorについて
Hibernate Validator 4はJSR303 - Bean Validationの参照実装で、JavaBeansに対するバリデーションフレームワークです。かなり手軽に使えるので個人的に気に入ってます。Bean Validationのインターフェースを実装し、独自の追加バリデータを作成するのも比較的簡単です。ということで今回はHibernate Validatorについて少し説明したいと思います。なお、サンプルプログラムで利用しているHibernate Validatorのバージョンは4.2です。
HibernateValidatorのバリデーションメッセージはデフォルトで英語なので、実開発時は日本語のメッセージを出力できたほうがいいと思います。メッセージはValidationMessages.propertiesにkey=value形式で定義し、クラスパスルートに当該ファイルを配置する必要があります。メッセージサンプルは以下の通りです。
サンプルメッセージ
#Japanesemessages javax.validation.constraints.AssertFalse.message=Falseでなければなりません。 javax.validation.constraints.AssertTrue.message=Trueでなければなりません。 javax.validation.constraints.DecimalMax.message={value}以下でなければなりません。 javax.validation.constraints.DecimalMin.message={value}以上でなければなりません。 javax.validation.constraints.Digits.message=境界以外の数値(予測:<{integer}digits>.<{fraction}digits>) javax.validation.constraints.Future.message=未来日付でなければなりません。 javax.validation.constraints.Max.message={value}以下でなければなりません。 javax.validation.constraints.Min.message={value}以上でなければなりません。 javax.validation.constraints.NotNull.message=Nullは許可されていません。 javax.validation.constraints.Null.message=Nullでなければなりません。 javax.validation.constraints.Past.message=過去日付でなければなりません。 javax.validation.constraints.Pattern.message=パターン({regexp})に一致しなければなりません。 javax.validation.constraints.Size.message=サイズは{min}以上{max}以下でなければなりません。 org.hibernate.validator.constraints.CreditCardNumber.message=正しいクレジットカード番号ではありません。 org.hibernate.validator.constraints.Email.message=正しいE-Mailの形式ではありません。 org.hibernate.validator.constraints.Length.message=長さは{min}以上{max}以下でなければなりません。 org.hibernate.validator.constraints.NotBlank.message=ブランクは許可されていません。 org.hibernate.validator.constraints.NotEmpty.message=何らかのデータが必要です。 org.hibernate.validator.constraints.Range.message={min}から{max}の範囲内でなければなりません。 org.hibernate.validator.constraints.SafeHtml.message=安全ではないHTMLが含まれています。 org.hibernate.validator.constraints.ScriptAssert.message={script}による評価が不正です。 org.hibernate.validator.constraints.URL.message=正しいURLではありません。
適当に直訳しただけなので、イケてないメッセージもありますがあくまでもサンプルなので...
それでは早速、まず、以下のようなJavaBeansをHibernateValidatorでチェックするとどうなるでしょうか?
class ValidatedBean { @NotNull private String userId; @Email private String email; ValidatedBean(){} String getUserId() { return userId; } void setUserId(String userId) { this.userId = userId; } String getEmail() { return email; } void setEmail(String email) { this.email = email; } }
上記JavaBeansのuserIdとemailプロパティにはそれぞれ@NotNullと@Emailのバリデータアノテーションが付与されています。
バリデーションプログラムは次の通りです。
import java.util.Iterator; import java.util.Set; import javax.validation.ConstraintViolation; import javax.validation.Validation; import javax.validation.Validator; import javax.validation.ValidatorFactory; import javax.validation.constraints.NotNull; import org.hibernate.validator.constraints.Email; public class Main { public static void main(String[] args) { ValidatedBean bean = getBean(); ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); Validator validator = factory.getValidator(); Set<ConstraintViolation<ValidatedBean>> constraintViolations = validator.validate(bean); if (constraintViolations.size() > 0) { Iterator<ConstraintViolation<ValidatedBean>> iterator = constraintViolations.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next().getMessage()); } } } private static ValidatedBean getBean() { ValidatedBean bean = new ValidatedBean(); return bean; } }
HibernateValiadtorを利用するには、まずValidationクラスのbuildDefaultValidatorFactoryメソッドよりValidatorFactoryクラスを取得します。取得したValidatorFactoryクラスのgetValidatorメソッドよりValidatorクラスを取得しvalidatorクラスのvalidateメソッドにバリデーション対象のBeanを渡すことでバリデーションの結果を受け取ることが可能です。
バリデーション結果はConstraintViolationのSetとして帰ってきます。検査エラーが1件でもある場合はSetのサイズが1以上となるため、結果メッセージを表示するにはiteratorでループし、ConstraintViolationのgetMessageメソッドで表示します。
上記バリデーションの結果はuserIdプロパティにNullが許可されていないため、サンプルメッセージの「Nullは許可されていません。」というメッセージが出力されます。@Emailは?と思われたかもしれませんが、@EmailアノテーションはEmailのフォーマットにあっているかどうかを検査するものであり、null値の場合は検査OKとなります。従ってemailプロパティがnullを許容したくない場合は@NotNullアノテーションを追加してやる必要があります。
emailプロパティにnullを許可させない場合。
@NotNull @Email private String email;
それでは、取得したBeanに対してsetEmailメソッドに"xyz"という文字列を渡してバリデーションを行うとどうなるでしょうか。
ValidatedBean bean = getBean(); bean.setEmail("xyz"); ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); Validator validator = factory.getValidator(); Set<ConstraintViolation<ValidatedBean>> constraintViolations = validator.validate(bean); if (constraintViolations.size() > 0) { Iterator<ConstraintViolation<ValidatedBean>> iterator = constraintViolations.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next().getMessage()); } }
結果はuserIdのNotNull制約違反のメッセージに加えて「正しいE-Mailの形式ではありません。」というメッセージが出力されると思います。
HibernateValidator(Bean Validation)には今回紹介した以外にも様々なバリデータがあります。(バリデーションの種類は上記メッセージサンプルの種類だけ存在します。)
また、Bean Validationの追加バリデーションライブラリとしてm4hv-extensionsという日本語向のバリデーションライブラリも以下のサイトで公開しています。
プロジェクトトップ:http://maru.sourceforge.jp/
ドキュメントサイト:http://maru.sourceforge.jp/m4hv-extensions/document.html