Spring Batch 6 のプログラムにデータ検証機能(Validation)を実装してみる。
パラメータ(ジョブ引数)のチェックをするのだが、
- パラメータとして渡せるのは models、modelName の二つだけ
- 必須項目はなし
- models が設定されたときは、数値でなければならない(異常終了)
- modelName の中身はなんでも良い
という仕様で組み込んでみる。(元ネタは「出力項目を増やすようちょっと修正版 Spring Batch」→「Spring Batch 6 で Listener を追加してログを出す」のソース)
■Validator/OptionalValidator.java
単純な必須チェックなどではない、独自チェックを記述したクラス
package com.netandfield.test.Validator;import org.springframework.batch.core.job.parameters.InvalidJobParametersException;import org.springframework.batch.core.job.parameters.JobParameters;import org.springframework.batch.core.job.parameters.JobParametersValidator;public class OptionalValidator implements JobParametersValidator {@Overridepublic void validate(JobParameters parameters) throws InvalidJobParametersException {// パラメーター取得String models = parameters.getString("models");;// 存在チェック(必須項目ではない)if (models == null || models.isEmpty()) {return;}// 存在していれば数値でなければならないtry {Integer.parseInt(models);}catch(NumberFormatException e) {throw new InvalidJobParametersException("Not Number: models=" + models);}}}
■Config/BatchConfig.java
import の追加
import java.util.ArrayList;import java.util.List;import org.springframework.batch.core.job.parameters.CompositeJobParametersValidator;import org.springframework.batch.core.job.parameters.DefaultJobParametersValidator;import org.springframework.batch.core.job.parameters.JobParametersValidator;import com.netandfield.test.Validator.OptionalValidator; // 作成した validator
バリデータの定義(使用可能なパラメータ(必須項目と任意項目))を追加
@Beanpublic DefaultJobParametersValidator defaultValidator() {// 1. 必須パラメータの配列String[] requiredKeys = {}; // 必須項目はなし// 2. 任意パラメータの配列String[] optionalKeys = {"models", "modelName"};// コンストラクタに(必須, 任意)の順番で渡すreturn new DefaultJobParametersValidator(requiredKeys, optionalKeys);}
作成した Validator(OptionalValidator クラス)を
CompositeJobParametersValidator(コンポジット・ジョブパラメータ・バリデータ)に追加
@Beanpublic JobParametersValidator compositeValidator() {// Validator List 生成List<JobParametersValidator> validators = new ArrayList<>();validators.add(defaultValidator());validators.add(new OptionalValidator());// Composit に Validator を入れるCompositeJobParametersValidator compositValidator = new CompositeJobParametersValidator();compositValidator.setValidators(validators);return compositValidator;}
Spring Batch では、1つの Job で 1つの Validator しかセットできない。
具体的には、Jobクラス(exportJob)の中で .validator() で指定できるクラスが 1つだけなので、使用可能なパラメータをチェックする標準の Validator(defaultValidator)クラスと、独自チェックの Validator(OptionalValidator)クラスを compositeValidator クラスにまとめ、.validator(compositeValidator()) と指定するわけ。
まとめた Validator を JobBuilder のメソッドチェーンに追加する。
@Beanpublic Job exportJob(Step exportStep) {return new JobBuilder("exportJob", jobRepository).start(exportStep).listener(jobListener) // JobExecutionListenerを追加.validator(compositeValidator()) // ValidatorをまとめたcompositeValidatorを追加.build();}
これで、完了。
実際に実行(「実行の構成」でプログラムの引数を指定)してみる。
パラメータ(引数)が「models=1 modelName=未来電話 mondamin=あり」のとき(許されていないパラメータ "mondamin" あり)
■実行結果ログ(長いので先頭を "~" で省略)
<略>~ : Running default command line with: [models=1, modelName=未来電話, mondamin=あり]~ : The JobParameters contains keys that are not explicitly optional or required: [mondamin]~ : [{JobParameter{name='models', value=1, type=class java.lang.String, identifying=true},JobParameter{name='modelName', value=未来電話, type=class java.lang.String, identifying=true},JobParameter{name='mondamin', value=あり, type=class java.lang.String, identifying=true}}]~ : The JobParameters contains keys that are not explicitly optional or required: [mondamin]<略>
と、"mondamin" が「The JobParameters contains keys that are not explicitly optional or required」(JobParameters に、明示的なオプション(任意)または必須として定義されていないキーが含まれています。)と警告されるが、処理は最後まで通る。
「え?InvalidJobParametersException は発生しないの?」って話だが、実は今回の処理には「必須項目」がないので、defaultValidator は自動的に「緩いチェック」にモードを切り替えてしまう。「必須項目」があれば、Spring Batch は「厳格チェックモード」に入り「未定義のパラメータが渡されたら異常終了」するようになる・・・らしい(^^;;;
俺的には「らしい」としか言えないので、エロい人、コメントで詳細教えて(笑)
次に、数値でなければいけないパラメータに「あ」をセットした場合の動きを見てみる。
パラメータ(引数)を「models=あ modelName=未来電話」とする。
■実行結果ログ(長いので先頭を "~" で省略)
これは、以下のようなログを吐いて無事落ちる。
<略>at com.netandfield.test.BatchDb2Csv1Application.main(BatchDb2Csv1Application.java:10) ~[classes/:na]at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:52) ~[spring-boot-devtools-4.1.0.jar:4.1.0]Caused by: org.springframework.batch.core.job.parameters.InvalidJobParametersException: Not Number: models=あat com.netandfield.test.Validator.OptionalValidator.validate(OptionalValidator.java:25) ~[classes/:na]at org.springframework.batch.core.job.parameters.CompositeJobParametersValidator.validate(CompositeJobParametersValidator.java:45) ~[spring-batch-core-6.0.4.jar:6.0.4]at org.springframework.batch.core.launch.support.TaskExecutorJobLauncher.createJobExecution(TaskExecutorJobLauncher.java:191) ~[spring-batch-core-6.0.4.jar:6.0.4]
しかし、ぱっと見、「Not Number: models=あ」が見つけられなくて、別の理由で落ちてるのかと思って必死で原因を探したわ(笑)
ああ、年を取って目がしょぼしょぼするのよ(笑)

コメントする