Bean Validation のエラーメッセージに任意のフィールド名を埋め込む方法を調べたときのメモ。タイトルには Bean Validation と書いていますが、正確には Spring が提供する機能によってエラーメッセージに任意のフィールド名を埋め込みます。
サンプルコード。
バリデーション用のアノテーションは以下の通り。
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @Constraint(validatedBy = { SampleValidator.class }) public @interface SampleValidation { String value(); String message() default "{com.example.demo.constraint.SampleValidation.message}"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }
今回は Controller で @Validated
を利用して Form バリデーションをするパターン。
@RestController public class DemoController { @Autowired MessageSource messageSource; @PostMapping("index") public String index(@RequestBody @Validated FooForm form, Errors errors) { if (errors.hasErrors()) { errors.getAllErrors().stream() .map(e -> messageSource.getMessage(e, Locale.getDefault())) .forEach(System.out::println); return "NG"; } return "OK"; } static class FooForm { @SampleValidation("foo") private String name; // バリデーション対象のフィールド public String getName() { return name; } public void setName(String name) { this.name = name; } } }
パターン1
プロパティ未定義の場合、Form クラスのフィールド名がメッセージ定義の {0}
にそのまま出力される。
com.example.demo.constraint.SampleValidation.message={0} is invalid.
出力結果:
> name is invalid.
パターン2
フィールド名をキーにしてプロパティを定義した場合、定義した名前がメッセージ定義の {0}
に埋め込まれて出力される。<Bean 名>.<フィールド名>
形式も可。
com.example.demo.constraint.SampleValidation.message={0} is invalid. name=Name
出力結果:
> Name is invalid.
パターン3
<フィールド名>
形式と <Bean 名>.<フィールド名>
形式を一緒に定義した場合、<Bean 名>.<フィールド名>
形式のプロパティが優先される。
com.example.demo.constraint.SampleValidation.message={0} is invalid. name=Name fooForm.name=NAME
出力結果:
> NAME is invalid.
現場からは以上です。