概要
Spring MVCにてフォームの入力チェックを行う方法についてまとめた。
今回はSpring Validatorを使用して相関チェックを行う方法について紹介する。
前提
当記事を紹介するうえでの前提情報は以下となる。
内部サイトリンク
入力チェックに必要な情報。
概要 Springのメッセージ管理を行うMessageSourceを使用して外部ファイルからメッセージを取得する方法についてまとめた。 MessageSourceはプロパティファイルに定義したメッセージを取得する機能を提供する。 […]
概要 Spring MVCにてフォームの入力チェックを行うための準備と入力チェックの全体像についてまとめた。 入力チェックにはBean Validationを使用する。 Bean Validationの機能を使用するためには、その実装[…]
概要 Spring MVCにてフォームの入力チェックを行う方法についてまとめた。 入力チェックには、フォームのフィールドに入力チェック用のアノテーションを付与する。 今回は基礎的なBean Validationと、その実装であるH[…]
概要 Spring MVCにてフォームの入力チェックを行う方法についてまとめた。 今回は独自の単項目入力チェックルールを作成する方法について紹介する。 前提 入力チェックに必要な情報は以下となる。 [sit[…]
フォーム
単項目チェックを行うアノテーションをパスワードフィールドに付与した状態で話を進める。
FooForm.java
@Data
public class FooForm implements Serializable {
// フォーム部品を追加していく
// パスワード
@Alphanumeric
private String password;
// 確認用パスワード
private String confirmPassword;
}
入力チェック作成の流れ
入力チェックは以下の流れで作成する。
・WebDataBinderに登録
それぞれの実装方法について解説する。
Spring Validatorの実装
Spring Validatorは「org.springframework.validation.Validator」を実装する。
今回作成する入力チェックは、「Bean Validationによる単項目チェックを行った後、エラーがなければ引き続き相関チェックを行う」という処理で作成する。
Spring Validator実装時には以下のメソッドをオーバーライドする。
・validate:バリデーションチェックを行う。
パスワードチェック用バリデーションクラス
「パスワード」と「パスワード(確認用)」の入力値が一致しているかどうかをチェックするクラスを作成する。
PasswordMatchValidator.java
@Component
public class PasswordMatchValidator implements Validator { // ①
@Override
public boolean supports(Class<?> clazz) {
return FooForm.class.isAssignableFrom(clazz); // ②
}
@Override
public void validate(Object target, Errors errors) {
if (errors.hasErrors()) { // ③
return;
}
// フィールドの値を取得 ④
BeanWrapperImpl beanWrapper = new BeanWrapperImpl(target);
Object propertyValue = beanWrapper.getPropertyValue("password");
Object comparingPropertyValue = beanWrapper.getPropertyValue("confirmPassword");
boolean res = ObjectUtils.nullSafeEquals(propertyValue, comparingPropertyValue);
// フィールドの比較
if (!res) {
errors.rejectValue("confirmPassword", "PasswordMismatch.message"); // ⑤
}
}
}
Validatorインターフェースを実装する。
引数で渡されたフォームが、FooFormまたはそのサブクラスかどうかを判定する。
Bean Validationによる単項目チェックエラーが既に存在するかどうかを判定する。
既にエラーが存在する場合、相関チェック処理は通さない。
BeanWrapperImpl beanWrapper = new BeanWrapperImpl(target);
Object propertyValue = beanWrapper.getPropertyValue(“password”);
Object comparingPropertyValue = beanWrapper.getPropertyValue(“confirmPassword”);
boolean res = ObjectUtils.nullSafeEquals(propertyValue, comparingPropertyValue);
フィールド名よりフォームに格納された値を取得し、「パスワード」と「パスワード(確認用)」の値を比較している。
以下の記事にてBeanWrapperImplの使い方を解説している。
概要 Spring MVCにてフォームの入力チェックを行う方法についてまとめた。 今回は相関チェックルールを作成する方法について紹介する。 前提 入力チェックに必要な情報は以下となる。
「パスワード」と「パスワード(確認用)」の値が等しくない場合、「パスワード(確認用)」フィールドにエラーメッセージを表示する。
エラーメッセージキーは”PasswordMismatch.message”を指定している。
メッセージプロパティ
相関チェックエラーは以下のように定義している。
messages_ja.properties
PasswordMismatch.message=パスワードとパスワード(確認用)の値が一致しません。
WebDataBinderに登録
作成したバリデーションクラスはWebDataBinderに登録する。
FooController.java
@Controller
@RequestMapping(value = "foo")
public class FooController {
@Autowired // ①
private PasswordMatchValidator passwordMatchValidator;
@InitBinder // ②
protected void initBinder(WebDataBinder binder) {
// カスタムバリデーションの登録 ③
binder.addValidators(passwordMatchValidator);
}
// フォーム入力画面へリダイレクト
@GetMapping("/")
public String top() {
return "redirect:/foo/input";
}
// フォーム入力画面表示
@GetMapping(value = "input")
public String input(Model model) {
model.addAttribute("fooForm", new FooForm());
return "foo/input";
}
// 送信パラメータの取得
@PostMapping(value = "input", params = "send")
public String send(@Validated @ModelAttribute("fooForm") FooForm form, BindingResult rs) {
if (rs.hasErrors()) {
// 入力エラー
return "foo/input";
}
return "redirect:/foo/input";
}
}
private PasswordMatchValidator passwordMatchValidator;
作成したバリデーションクラスをインジェクションする。
バインダーの初期化用アノテーション。
リクエストごとに1回、WebDataBinderをカスタマイズするために使用する。
binder.addValidators(passwordMatchValidator);
WebDataBinderは、リクエストパラメータとフォームのデータバインディングを行う。
上記はWebDataBinderにインジェクションしたバリデーションクラスを登録している。
これにより、以下の流れで作成した相関チェック処理を実行することができる。
(2)FooForm内で@Validated による自動バリデーションを行う
(3)PasswordMatchValidatorによるバリデーションを行う
実行結果
実際に入力チェックエラーを起こすと以下のようになる。
※パスワードフィールドのため、入力内容が残らず未入力のように見えてしまうが実際は入力している