【Spring MVC】フォームの入力チェック方法(Spring Validatorによる相関チェックルールの追加)

概要

Spring MVCにてフォームの入力チェックを行う方法についてまとめた。
今回はSpring Validatorを使用して相関チェックを行う方法について紹介する。

 

前提

当記事を紹介するうえでの前提情報は以下となる。

内部サイトリンク

入力チェックに必要な情報。

メッセージプロパティ定義

概要 Springのメッセージ管理を行うMessageSourceを使用して外部ファイルからメッセージを取得する方法についてまとめた。 MessageSourceはプロパティファイルに定義したメッセージを取得する機能を提供する。 […]

【Spring MVC】MessageSourceを使用する方法
入力チェックに必要な資材

概要 Spring MVCにてフォームの入力チェックを行うための準備と入力チェックの全体像についてまとめた。 入力チェックにはBean Validationを使用する。 Bean Validationの機能を使用するためには、その実装[…]

【Spring MVC】フォームの入力チェック方法(準備)
アノテーションの基本的な使い方

概要 Spring MVCにてフォームの入力チェックを行う方法についてまとめた。 入力チェックには、フォームのフィールドに入力チェック用のアノテーションを付与する。 今回は基礎的なBean Validationと、その実装であるH[…]

【Spring MVC】フォームの入力チェック方法(基本な使い方)
アノテーションクラスの作成方法

概要 Spring MVCにてフォームの入力チェックを行う方法についてまとめた。 今回は独自の単項目入力チェックルールを作成する方法について紹介する。   前提 入力チェックに必要な情報は以下となる。 [sit[…]

【Spring MVC】フォームの入力チェック方法(独自単項目チェックルールの追加)

 

フォーム

単項目チェックを行うアノテーションをパスワードフィールドに付与した状態で話を進める。

FooForm.java


@Data	
public class FooForm implements Serializable {	
	// フォーム部品を追加していく
	// パスワード
	@Alphanumeric
	private String password;
	// 確認用パスワード
	private String confirmPassword;
}	

 

入力チェック作成の流れ

入力チェックは以下の流れで作成する。

・Spring Validatorの実装
・WebDataBinderに登録

それぞれの実装方法について解説する。

Spring Validatorの実装

Spring Validatorは「org.springframework.validation.Validator」を実装する。
今回作成する入力チェックは、「Bean Validationによる単項目チェックを行った後、エラーがなければ引き続き相関チェックを行う」という処理で作成する。

Spring Validator実装時には以下のメソッドをオーバーライドする。

・supports:引数で渡されたクラスがチェック対象のクラスまたはサブクラスかどうかを判定する。チェック対象の場合、validateメソッドを呼び出す。

・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"); // ⑤
		}
	}

}		

 

public class PasswordMatchValidator implements Validator { // ①

Validatorインターフェースを実装する。

 

return FooForm.class.isAssignableFrom(clazz); // ②

引数で渡されたフォームが、FooFormまたはそのサブクラスかどうかを判定する。

 

if (errors.hasErrors()) { // ③

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にてフォームの入力チェックを行う方法についてまとめた。 今回は相関チェックルールを作成する方法について紹介する。   前提 入力チェックに必要な情報は以下となる。

【Spring MVC】フォームの入力チェック方法(相関チェックルールの追加)

 

errors.rejectValue(“confirmPassword”, “PasswordMismatch.message”); // ⑤

「パスワード」と「パスワード(確認用)」の値が等しくない場合、「パスワード(確認用)」フィールドにエラーメッセージを表示する。
エラーメッセージキーは”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";
	}
}

 

@Autowired // ①
private PasswordMatchValidator passwordMatchValidator;

作成したバリデーションクラスをインジェクションする。

 

@InitBinder // ②

バインダーの初期化用アノテーション。
リクエストごとに1回、WebDataBinderをカスタマイズするために使用する。

 

// カスタムバリデーションの登録 ③
binder.addValidators(passwordMatchValidator);

WebDataBinderは、リクエストパラメータとフォームのデータバインディングを行う。
上記はWebDataBinderにインジェクションしたバリデーションクラスを登録している。

これにより、以下の流れで作成した相関チェック処理を実行することができる。

(1)WebDataBinderが入力したフォームのデータをFooFormオブジェクトにバインド
(2)FooForm内で@Validated による自動バリデーションを行う
(3)PasswordMatchValidatorによるバリデーションを行う

 

実行結果

実際に入力チェックエラーを起こすと以下のようになる。
※パスワードフィールドのため、入力内容が残らず未入力のように見えてしまうが実際は入力している

 

【Spring MVCフォームの入力チェック方法(Spring Validatorによる相関チェックルールの追加)】_単項目エラー
▲単項目エラーが発生した場合(相関チェックは行われないためエラーメッセージが表示されない)

 

【Spring MVCフォームの入力チェック方法(Spring Validatorによる相関チェックルールの追加)】_相関チェックエラー
▲単項目チェックエラーにならない 且つ 相関チェックエラーの場合

 

 

 

スポンサーリンク