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

概要

Spring Batchでの妥当性チェックの方法をいくつか見てみましょう。

いくつか方法はありますが、まずは妥当性チェックなしのファイルの読み込み方法を見ておいていただけると良いかと思います。

参考: 06.バッチ処理の実際のサンプル(チャンク処理:ファイル読み込み)

上記の内容を把握していますと、後は簡単です。

といっても、以下のようにいくつかの方法があります。

【Spring Batch における妥当性チェックの実装方法】

①ItemProcessorのValidatingItemProcessorを使用する方法

②自作のFieldSetMapper内でValidateを実装する方法

③BeanWrapperFieldSetMapperのinitBinderをオーバーライドする方法

他にもあるかと思います。

Spring Batchのサンプルでよく紹介されるのは上記①かと思います。

おそらく③はあまり紹介している記事が少ないかと思いますので、①②を簡単に説明して③について詳しく見ていくことにします。

【エラーメッセージの出力】

妥当性チェックの結果のエラーコードをエラーメッセージに変換する方法は次の記事で見ることにします。

ここでは触れません。

【妥当性チェックのフレームワーク】 2014.08.03追記

以前のSpring Batchでは、妥当性チェックにはSpring Modulesを推奨していましたが現在廃止になっています。

使用しない方が良いでしょう。

では他の選択肢に何があるのでしょうか?

2014年現在では、世の中的にはHibernate Validatorを使用するのがスタンダードのようです。

Spring MVCの妥当性チェックもHibernate Validatorがデフォルトなので、統一性の意味でもSpringBatchでもそれを使うのが良いかと思います。

使い方のサンプルの記事を書きましたので参考にしていただければと思います。

参考: 82.参考:妥当性チェックにHibernate Validatorを使う

※もちろん、自作Validatorでも大丈夫です。

①ItemProcessorのValidatingItemProcessorを使用する方法

Spring Batchでは、妥当性チェックをする方法としてValidatingItemProcessorを用意しています。

この方法はItemReaderでファイルからデータを読み込んだ場合だけでなく、DBから読み込んだり、

他から読み込む場合でも使用できるという特徴があります。

【Spring設定ファイルのサンプル】

<bean id="validatingItemProcessor" class="org.springframework.batch.item.validator.ValidatingItemProcessor">

<property name="validator" ref="valangValidator" />

</bean>

上記のItemProcessorをJobのchunkタグのprocessor属性に設定するだけです。

妥当性チェックエラーが発生した場合はExceptionを投げます。

もしfilterプロパティをtrueに設定すると、妥当性チェックエラーのあったitemは無視します。

【Validatorについて】

上記のプロパティのvalidatorはパッケージ名に気を付けてください。

org.springframework.batch.item.validator.Validator です。

次の記事でも触れていますので参考にしていただければと思います。

参考: 99.Spring BatchのTips

【補足】

この方法は、ItemProcessorを使用しますので、ItemReaderで例外が発生した場合はここまで到達しません。

ItemReaderでの例外とは例えば、"suzuki"をintに変換しようとして失敗した、などの型変換エラーが含まれます。

エラーを細かく制御しなくて良い場合は特に問題ありません。

しかし、型変換エラーも妥当性チェックエラーと同じタイミングで処理したい場合や、型変換エラーと妥当性チェックエラーすべてをログ等に出したい場合、などは

この方法はあまり良くないと思います。型変換エラー(ItemReader)で例外が発生すれば、上記のItemProcessorまで行く前に処理が異常終了するからです。

問題の解決のため、以下の②、③の方法も検討してみてください。

②自作のFieldSetMapper内でValidateを実装する方法

ファイル読み込みのサンプルで見た、FieldSetMapperの派生クラスを自作するする方法の延長です。

参考: 06.バッチ処理の実際のサンプル(チャンク処理:ファイル読み込み)

Spring MVCなどでも行う方法ですので、特に詳しくは触れません。

BindExceptionにエラーを追加していくだけです。

【サンプル】

public class MemberFieldSetMapper implements FieldSetMapper<Member> {

@Override

public Member mapFieldSet(FieldSet fs) throws BindException {

Member member = new Member();

member.setNum(fs.readInt("num", 0));

member.setName(fs.readString("name"));

//妥当性チェック(checkKanjiは漢字かどうかをチェックするメソッド。各自作成してみてください)

BindException e = new BindException(member, "member");

if(!checkKanji(member.getName())){

e.rejectValue("name", "error.kanji", "名前は感じです");

}

ValidationUtils.rejectIfEmpty(e, "name", "name.empty");

if(e.hasErrors()){

throw e;

}

return member;

}

}

Springでよくやる方法ですので、特に詳しい説明はしません。

BindExceptionでは、チェックするオブジェクトと結び付けて、rejectやrejectValueメソッドでエラー内容を追加していきます。

また、ValidationUtilsを使用するとEmptyの妥当性チェックくらいはできます。

最後にエラーが存在すればそのままthrowします。

【補足】

上記は手で1つ1つ、rejectValue()などで妥当性チェックを記述しています。

これでもよいですし、Springの既存のValidatorをDI して使用しても良いです。

validator.validate(member, e); のように妥当性チェックを実行し、あとは上記と同じようにBindExceptionをthrowするだけです。

③BeanWrapperFieldSetMapperのinitBinderをオーバーライドする方法

BeanWrapperFieldSetMapperは、Spring Batchが用意しているクラスです。

自作のPOJOに値を自動的に設定します。

このクラス自身はValidateする方法を持っていません。

しかし、ちょっとオーバーライドするだけで妥当性チェックさせることもできます。

【サンプル】

public class BeanWrapperValidateFieldSetMapper<T> extends

BeanWrapperFieldSetMapper<T>{

static private Log log = LogFactory.getLog(BeanWrapperValidateFieldSetMapper.class);

private Validator validator;

@Override

protected void initBinder(DataBinder binder) {

binder.setValidator(this.validator);

}

//accessor-------------------------------

public void setValidator(Validator validator) {

this.validator = validator;

}

}

initBinderメソッドをオーバーライドして、BinderにValidatorを設定するだけです。

また、このとき、binder.registerCustomEditor()メソッドを呼び出せば、日付の書式や数字の書式も設定できます。

【Binder について】

Binderの役割は、値をPOJOに設定することと、型変換エラーや妥当性チェックを行うことです。

ですので上記のようにBinderの初期化でそれらの設定をすることができます。

参考: 03.基本概念:バインダー(Binder)とは

【Validator について】

ValiatorインターフェースはSpringのコア機能として用意しているものと、Spring Batchがそれとの橋渡しとして用意しているもの

2つがあります。

上記のサンプルでは、BinderというSpringのコア機能を使用するので、コア機能のValidatorを使用します。

つまり、org.springframework.validation.Validator です。

Created Date: 2012/04/28