81.参考: 妥当性チェックの
エラーメッセージ出力方法

概要

Spring Batchでは妥当性チェックをする方法をいくつか用意しています。

参考: 80.参考: ファイル読み込み妥当性チェック (FlatFileItemReader)

妥当性チェックの結果はBindExceptionに保存されます。

BindException は、エラーコード(例:"errors.required")を持っているだけで、

それをエラーメッセージ(例:"名前は必須です") に変換してくれません。

エラーメッセージに変換する方法はSpringのコア機能が持っているのですが、

あまりSpringに触れたことがない方はこのあたり分からないかもしれないですね。

そこで、ここで軽く触れてみようかと思います。

BindExceptionからエラーメッセージに変換する

BindExceptionには、1つのオブジェクト(妥当性チェックの対象)に対するエラーが複数保存されています。

ですので、ループさせてメッセージを出力していくサンプルを見ます。

【サンプル】

private MessageSource messageSource;

protected void printMsg(BindException errors){

for(ObjectError err : errors.getAllErrors()){

String msg = this.messageSource.getMessage(err, Locale.getDefault());

System.out.println(msg);

}

}

messageSourceのsetterは各自用意しておいてください。

printMsgにBindExceptionを渡せば標準出力にエラーメッセージを出力していきます。

messageSourceでは、エラーコードとエラーメッセージを記述したpropertiesファイルを読み込むようにしておきます。

通常、messageSourceには、org.springframework.context.support.ResourceBundleMessageSource を使用します。

BindExceptionのエラーメッセージ変換の補足

Springのエラーメッセージの変換はおもしろいので補足しておきます。

上記のMessageSource.getMessage(MessageSourceResolvable, java.util.Locale) のMessageSourceResolvableを見ていきます。

Binderがエラーを保存してエラーメッセージを出力するまでの大まかな流れ

妥当性チェックエラーや型変換エラーは、Binderが捕捉します。(Binderについて知りたい方はこちら

Binderは捕捉したエラーをBindExceptionに保管させます。

【エラー保存からエラーメッセージまでの大まかな流れ(イメージ)】

①BinderがBindExceptionにエラーを設定する

//チェック対象のuserオブジェクトの設定。userには値が設定されているものとします

BindException errors = new BindException(user, "user");

//エラーを設定する

errors.rejectValue("age", "typeMissmatch");

errors.reject("error.somethig");

正確にはBinderが妥当性チェックをするValidatorを持っていて、Validatorが上記のようなことをします。

Springが用意したVaidatorを使うこともできますし、上記のようなコードを自作しても良いです。

エラーの保管方法は、rejectValue(), reject()の2つがあります。

rejectValueがよく使うモデルPOJOのフィールドごとのエラーを保管するもので、引数にもフィールド名ageを指定しています。

もうひとつのrejectはフィールドに関わらないエラーを保管します。

いずれにしてもポイントは、BindException内部にエラーコードを保管していることです。

②次に、BindExceptionからエラーオブジェクトを取得する

for(ObjectError err : errors.getAllErrors()){

エラーからエラーオブジェクトを取得します。

rejectValue(), reject()で保管したエラーの両方ともを取得します。

もしrejectValue()で保管したエラーだけを取得したい場合はgetFieldErrors()やgetFieldError()などを使用します。

③最後に、エラーオブジェクトをエラーメッセージに変換します

String msg = this.messageSource.getMessage(err, Locale.getDefault());

取得したObjectErrorをエラーメッセージに変換します。

getMessageの第一引数は、MessageSourceResolvableインターフェースです。

ObjectErrorは、DefaultMessageCodesResolverをextendsしていますので引数に指定できます。

DefaultMessageCodesResolverはもちろんMessageCodesResolverをimplementsしています。

【DefaultMessageCodesResolverについて】

このクラスは、エラーコードを以下のルールで複数作成します。

そして、getMessage()は、作成された複数のエラーコードを順番に検索し、最初に見つかったメッセージを採用します。

<rejectValueされたエラーで作成されるエラーコードと優先順位>

1: エラーコード + "." + オブジェクト名 + "." + フィールド名

2: エラーコード + "." + フィールド名

3: エラーコード + "." + 型

4: エラーコード

上記のサンプルの場合の例:

1: "typeMismatch.user.age"

2: "typeMismatch.age"

3: "typeMismatch.int"

4: "typeMismatch"

<rejectされたエラーで作成されるエラーコードと優先順位>

1: エラーコード + "." + オブジェクト名

2: エラーコード

上記のサンプルの場合の例:

1: "error.something.user"

4: "error.something"

このようにして、Springはエラーとエラーメッセージを解決していきます。

面白いですね。

Created Date: 2012/04/28