まめログ

Javaプログラマの歩み

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";
    }