依存関係の追加
spring-boot-starter-validationの依存関係を追加する。
gradleを使用している場合、以下の記述をbuild.gradleに追加する。
// Hibernate Validator で Java Bean Validation を使用するためのスターター implementation 'org.springframework.boot:spring-boot-starter-validation'
アノテーションの付加
バリデーションをしたいフィールドにアノテーションを付与する。
4つのフィールドに下表のような入力チェックを適用するためにアノテーションを付与する例を示す。
フィールド | チェック項目 |
---|---|
name | 必須チェック |
mailAddress | 必須チェック メールアドレスチェック |
age | 範囲チェック(0から100歳まで) |
birthday | 過去日チェック |
import java.time.LocalDate; import javax.validation.constraints.Email; import javax.validation.constraints.NotBlank; import javax.validation.constraints.Past; import org.hibernate.validator.constraints.Range; import lombok.Data; /** * サンプルModel。<br> */ @Data public class SampleModel { /** 名前 */ @NotBlank private String name; /** メールアドレス */ @Email @NotBlank private String mailAddress; /** 年齢 */ @Range(min = 0, max = 100) private int age; /** 誕生日 */ @Past @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate birthday; }
バリデーションの実行
バリデーション実行方法を2種類以下に示す。
リクエストを受け取ったタイミングで実行(@Validated)
コントローラーで@Validatedを付与することで、入力値のバリデーションが実行される。
バリデーションの結果はBindingResult
に入るため、メソッドの引数に追加する。
import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller public class SampleController { @RequestMapping(value = "/result", method = RequestMethod.POST) public String result(@ModelAttribute @Validated SampleModel sm, BindingResult result, Model model) { if (result.hasErrors()) { model.addAttribute("sm", sm); return "index"; } return "result"; } }
任意のタイミングで実行(SmartValidatorの使用)
コンストラクタインジェクションでSmartValidatorをDIし、validateメソッドを呼び出すことでバリデーションが実行される。
エラーメッセージを受け取る場合はBindingResultをメソッドの引数に追加する。
import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.validation.SmartValidator; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller public class SampleController { public SmartValidator validator; public ValidationSampleController(SmartValidator validator) { this.validator = validator; } @RequestMapping(value = "/validationResult", method = RequestMethod.POST) public String result(@ModelAttribute ValidationSampleModel vm, BindingResult result, Model model) { validator.validate(vm, result); if (result.hasErrors()) { model.addAttribute("validationSampleModel", vm); return "validationSample"; } return "validationResult"; } }
エラーメッセージの画面表示(Thymeleaf使用の場合)
エラーメッセージは以下の記述で表示される。
th:errors="*{バリデーションNGだったフィールド名}"
@Validated が付与されたインスタンスの指定も必要であり、formタグにth:object="${インスタンス名}" 属性を追加する。
指定するインスタンス名は、コントローラクラスでmodel.addAttribute("sm", sm);
の記述で設定した名前(sm)ではなく、
Spring内で自動的に解決した名前となるため、留意する。参考
<!DOCTYPE html> <html xmlns:th="<http://www.thymeleaf.org>"> <head> <meta charset="UTF-8"> <title>index</title> </head> <body> <h2 th:text="Home"></h2> <form th:action="@{/result}" th:object="${sampleModel}" method="post"> <div>名前</div> <div><input type="text" th:field="*{name}" /></div> <span th:if="${#fields.hasErrors('name')}" th:errors="*{name}" style="color: red"></span> <div>メールアドレス</div> <div><input type="text" th:field="*{mailAddress}" /></div> <span th:if="${#fields.hasErrors('mailAddress')}" th:errors="*{mailAddress}" style="color: red"></span> <div>年齢</div> <div><input type="number" th:field="*{age}" /></div> <span th:if="${#fields.hasErrors('age')}" th:errors="*{age}" style="color: red" ></span> <div>誕生日</div> <div><input type="date" th:field="*{birthday}" /></div> <span th:if="${#fields.hasErrors('birthday')}" th:errors="*{birthday}" style="color: red"></span> <p><input type="submit" value="送信" /></p> </form> </body> </html>
バリデーションのエラーメッセージの変更
バリデーションエラー時のメッセージは特に設定のない場合、デフォルトで設定されているメッセージとなる。
独自のメッセージに変更する方法を以下に示す。
1. 特定のクラスの特定のバリデーションのメッセージを変更する場合は、付与したアノテーションにmessage属性を追加する。
/** 名前 */ @NotBlank(message = "必須入力です") private String name;
2. 特定のバリデーションのデフォルトメッセージを変更する場合はsrc/main/resourceにValidationMessages.properties
を作成する。
以下は@NotBlank
のデフォルトメッセージを変更する際の記述例である。
入力された値をメッセージに表示したい場合は${validatedValue}
を使用する。
{0}
でエラーしたフィールド名が取得できる。
javax.validation.constraints.NotBlank.message=必須入力です
# 「2030-12-31は未来日です。過去の日付を入力してください。」と表示される javax.validation.constraints.Past.message=${validatedValue}は未来日です。過去の日付を入力してください。
3. 特定のアノテーションのメッセージを変更する場合はsrc/main/resourceにmessages.properties
を作成する。
{0}
でエラーしたフィールド名が取得できる。
エラーしたフィールド名を日本語で表示したい場合も設定可能。
# 「nameは必須入力です」と表示される NotBlank={0}は必須入力です
# 「名前は必須入力です」と表示される name=名前 NotBlank={0}は必須入力です