Spring Boot + Thymeleafでバリデーションを実装する
バリデーションとは
Webアプリにおいて、ユーザが入力した値や送信されてきたデータが適切かどうかを判定する処理のこと。
適切なバリデーションを実装することで、システムにおける不正データでの流入を防ぐとともに、ユーザエクスペリエンスも向上させることができる。
主なバリデーション
バリデーションの内容には以下のようなものがある。
必須項目
必ず入力されていなければならない値のチェック
文字列の長さ
最小・最大長
データ型
数字、日付など
フォーマット検証
電話番号やメールアドレスなど
値の範囲
0~100など
Spring Bootとバリデーション
Spring BootではBean Validationという便利なバリデーション機能を提供しており、バリデーション定義をアノテーションベースで簡単に実装できる。
サーバサイドのエンティティクラスにアノテーションを付与することで、フロントエンドでのバリデーションが行える。
Bean Validationの導入
pom.xmlに以下のdependencyを追加する。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> <version>3.5.3</version> </dependency>
よく使うアノテーション
@NotNull 必須チェック(NULLの場合NG)
@NotEmpty|必須チェック(NULL、空文字の場合NG)|
@Size 桁数チェック
@Min 数値の最小値チェック
@Max 数値の最大値チェック
@Email メールアドレスの書式
エンティティクラスにバリデーションを追加
バリデーションをつけたいフィールド変数の宣言の上にバリデーション用のアノテーションを付与することで、バリデーション定義を実装することができる。
@NotEmpty
private String artistName;
コントローラにバリデーション処理を組み込む
コントローラでバリデーション処理を実行するには、バリデーションを行いたいエンティティクラスの引数の前に@Validatedアノテーションを付与する。
public String registerArtist(@ModelAttribute @Validated Artist artist, @RequestParam("artist_cover") MultipartFile cover,Model model) {
}
バリデーション結果を格納する変数を用意する
コントローラで行われたバリデーション結果を格納するため、BindingResult型の変数をコントローラの該当メソッドの引数に追加する。
この際、バリデーション対象の引数の次の引数として宣言する必要があるので注意。
public String registerArtist(@ModelAttribute @Validated Artist artist, BindingResult result, @RequestParam("artist_cover") MultipartFile cover,Model model) {
}
バリデーション結果を判定する
バリデーションの結果のエラーの有無ははBidingResultのhasErrors()メソッドで取得することができる。
バリデーションエラーがあった際に、画面遷移先が異なる場合などには判定処理をいれる必要がある。
if(result.hasErrors()){
return "/artist/register"; //エラー時の遷移先
}
バリデーション結果を画面に表示する
エラー判定処理とエラー内容のタグを加える。
htmlには以下のようにタグを追加すれば、エラー発生時にエラー内容を表示することができる。
<div class="fw-bold" th:if="${#fields.hasErrors('artistName')}" th:errors="*{artistName}" th:errorclass="err" style="color:red"></div>Controllerでの判定処理は引数にBindingResult型の変数を追加することで行える。
@PostMapping("/artists")
public String registerArtist(@ModelAttribute @Validated Artist artist, BindingResult result, @RequestParam("artist_cover") MultipartFile cover,Model model) {
if(result.hasErrors()){
return "/artist/register";
}
artistService.registerArtist(artist,cover);
return "redirect:/artists";
}