概要
Spring MVCにてフォームの入力チェックを行うための準備と入力チェックの全体像についてまとめた。
入力チェックにはBean Validationを使用する。
Bean Validationの機能を使用するためには、その実装であるHibernate Validatorモジュールを追加してバリデーション機能を使用する必要がある。
入力チェック概要
必要な資材等の準備と入力チェック方法について紹介する。
事前準備
入力チェックを行うために、Hibernate Validatorモジュールとエラーメッセージなどを定義したプロパティファイルを用意する。
Hibernate Validatorモジュール
pom.xmlに必要なモジュールを追加する。
pom.xml
<!-- Hibernate Validatorを使用するためのモジュール -->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.1.7.Final</version>
</dependency>
上記モジュールを参照することで、入力チェックを行うためのアノテーションを使用することができる。
メッセージプロパティ
入力チェックエラー時、画面に表示するためのエラーメッセージをプロパティファイルから取得するため、プロパティファイルとMessageSourceを用意する。
作成方法は以下を参照。
概要 Springのメッセージ管理を行うMessageSourceを使用して外部ファイルからメッセージを取得する方法についてまとめた。 MessageSourceはプロパティファイルに定義したメッセージを取得する機能を提供する。 […]
未入力の制御
Spring MVCではテキストフィールドを未入力の状態で送信すると””(空文字)が送られる。
“”(空文字)ではなくNULLの方がアノテーションを使用した入力チェックを実装するうえで効果的なため、NULL変換を行う処理を追加する。
CommonControllerAdvice.java
package com.example.prototype.web.common;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;
@Component
@ControllerAdvice("com.example.prototype.web.controller") // ①
public class CommonControllerAdvice {
// フォームデータバインディング設定
@InitBinder // ②
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(String.class, new StringTrimmerEditor(true)); // ③
}
}
上記はAOP(アスペクト指向プログラミング)の記載。
指定したパッケージ配下のコントローラーに対して、ハンドラメソッド実行時にCommonControllerAdviceクラス内の該当する共通処理を行うことができる。
パラメータをオブジェクトにバインドする前に実行される処理。
今回だと指定したコントローラーパッケージ配下のハンドラメソッドが実行される前に処理がはしる。
WebDataBinderを用いて、フォームから送信される文字列データの処理方法をカスタマイズしている。
StringTrimmerEditorは文字列の前後にある不要な空白(スペース、タブ、改行など)を自動的にトリミングする。
また、コンストラクタにtrueを設定することで、トリミング後に空文字だった場合NULLに変換する。
入力チェックの全体像
入力チェックは以下の流れで行う。
②対応するメッセージ定義
③入力チェック有効化
④エラー情報表示
検証用のアノテーション付与
バリデーションを行うため、入力チェック用のアノテーションを対象のフィールドに付与する。
FooForm.java
// 名前
@NotNull
private String name;
対応するメッセージ定義
対象のアノテーション(入力チェック)にてエラーとなった場合の、エラーメッセージをメッセージプロパティに定義する。
messages_ja.properties
######################################
# プロパティ名
######################################
fooForm.name=お名前
######################################
# エラーメッセージ
######################################
# 汎用的なエラーメッセージ
NotNull.java.lang.String={0}は必須項目です。
######################################
# プロパティごとのエラーメッセージ
######################################
#NotNull.fooForm.name=お名前は必須項目です。
フィールド名を定義することで、エラーメッセージにフィールド名をバインドできる。
「入力チェックアノテーション名.型名」と定義することで、汎用的なエラーメッセージ内容を定義できる。
上記の{0}には定義したフィールド名がバインドされる。
コメントアウトしているが、 上記のようにフォームのフィールド名に対して直接入力チェックメッセージを指定することも可能。
入力チェック有効化
コントローラーにて@Validまたは@Validatedアノテーションを使用することで入力チェックを行う。
FooController.java
// 送信パラメータの取得
@PostMapping(value = "input", params = "send")
public String send(@Valid @ModelAttribute("fooForm") FooForm form, BindingResult rs) { // ①
if (rs.hasErrors()) { // ②
// 入力エラー
return "foo/input";
}
return "redirect:/foo/input";
}
@Validアノテーションをフォームオブジェクトの前に指定することでバリデーションが実行される。
バリデーションルールは対象のフォームオブジェクト内の各フィールドに付与した入力チェックアノテーションとなる。
バリデーションした結果はBindingResultオブジェクトに設定される。
BindingResultの上記のメソッドにてバリデーション結果を判定する。
エラーの場合、エラー情報を保持したBindingResultが自動的にModelに格納される。
エラー情報表示
バリデーションエラーメッセージ領域を定義する。
input.jsp
<tr>
<th class="col-3">名前</th>
<td class="col-7">
<form:input path="name" cssClass="form-control" />
<form:errors path="name" cssClass="text-danger" />
</td>
</tr>
バリデーションエラーとなった場合、画面側に返したBindingResultよりエラーメッセージをバインドする。
エラーメッセージは上記のようにフィールド毎に定義する。
定義したエラーメッセージは以下のように表示される。