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

ダウンロードサイト:http://sourceforge.jp/projects/maru/releases/