BeanValidationで日本語メッセージを出力する
BeanValidation1.0の参照実装であるHibernate Validatorのデフォルトメッセージは英語です。
例えば@NotNullでは「may not be null」、@AssertTrueでは「must be true」といったメッセージが出力されます。通常、JSF2.0を組み合わせて使うときには『"名前"が入力されていません』のように、日本語でかつ入力箇所をメッセージとして出力したいかと思います。
具体例を紹介すると、以下のようなコードを書いた場合のメッセージ表示についてです。
こんな入力フォーム(facelets/XHTML)を作って
<h:inputText id="isbn" label="ISBNコード" value="#{controller.book.isbn}" /> <br/> <h:message for="isbn" errorStyle="color:red"/>
こんな風にBean Validationを使うと
@Named public class Book { @Id @NotBlank private String isbn;
デフォルトではメッセージも英語で、入力コンポーネント名も出力されません。
ここでは、日本語メッセージと入力コンポーネントの表示方法についてまとめます。
1. Bean Validationのメッセージファイルを作る
Bean Validationの日本語メッセージは参照実装であるHibernate Validator4.3.1にはバンドルされていないため、ユーザにて作成します。
ValidationMessesages_jp_JP.properties
javax.faces.validator.BeanValidator.MESSAGE={1} {0} org.hibernate.validator.constraints.NotBlank.message=は必須入力です。
まずファイル名ですが、この名前はHibernate Validatorで決められているデフォルト名*1です。
また、格納フォルダのデフォルトではクラスパスのルートと決められています。そのため、自分は以下のようにsrc/main/resourcesに置いてみました。
次に内容についてです。
1行目の「javax.faces.validator.BeanValidator.MESSAGE={1} {0}」ですが、JSF2.0がライフサイクルの中でBeanValidationを実行した時、このキーのメッセージをFacesContextに登録しているようです(mojjaraのコード確認してないので、少し自信なし)。{0}にはBeanValidationのメッセージが代入されます。{1}には入力コンポーネントのlabel属性の設定値が代入されます。
この設定については、JSFの仕様書*2においても紹介されています。
このキーのメッセージはデフォルトでは「javax.faces.validator.BeanValidator.MESSAGE={0}」と定義されています。このため、最初に紹介したエラーメッセージ画像では、入力コンポーネントのlabel属性が表示されていません。
2行目は実際に画面に出力したい日本語のメッセージです。上記のようにキー値をBeanValidationのデフォルトと合わせておくと、アノテーション側でキーを明示的に指定せずに済みます。
例えば、以下のメッセージプロパティとした場合
notblank=は必須入力です。
@NotBlankのmessage属性を定義する必要があります。
@Id @NotBlank(message="{notblank}") private String isbn;
HibernateValidator4.3.1の場合、キー値の命名規則はアノテーションのFQDN+.messageとなっています。
2. faces-config.xmlに登録する
作成したファイルをJSFの設定として登録します。
BeanValidationの設定としては、classpathのルートにValidationMessages_XX.xmlを置くと自動的に読み込んでくれますが、JSFとしての設定をしないと入力コンポーネントが表示されずに「は必須です」としか出力されません。
faces-config.xmlの追記を忘れた場合
faces-config.xmlには以下の設定を追記します。
<application> <message-bundle>ValidationMessages</message-bundle> </application>
これで設定は終わりです。
設定がうまくいっていれば、以下のように入力コンポーネント名と日本語メッセージが出力されるようになると思います。
*1:参考1 Hibernate Validator Reference Guide 2.2.4. Message interpolation http://docs.jboss.org/hibernate/validator/4.3/reference/en-US/html_single/
*2:参考2 JavaServer Faces Specification Version2.1 2 3.5.6.3 Localization of Bean Validation Messages