JavaでTODOアプリを制作しよう13 TODOフォームのバリデーション1: 文字数制限・@Validatedを使うためのGradleの更新


こんにちは。

前回までに引き続き例外処理の実装を進めていきましょう!

TODOアプリ作成リンク集

1: [超基礎の理解] MVCの簡単な説明
2: [雛形を用意する] Spring Initializrで雛形を作ってHello worldしたい
3: [MySQLとの接続・設定・データの表示] MySQLに仮のデータを保存 -> 全取得 -> topに表示する
4: [POST機能] 投稿機能の実装
5: [PATCH機能] TODOの表示を切り替える
6: [JpaRepositoryの簡単な使い方] 検索機能の実装
7: [Thymeleaf テンプレートフラグメントで共通化] Headerの作成
8: [PUT機能] 編集機能の実装
9: [微調整]TODOの表示を作成日時が新しい順にソートする + 期日のデフォルトを今日の日付にする
10: [springで例外処理] 例外処理についての簡単なまとめ
11: [springで例外処理] 存在しないIDのTODOにアクセスした時の例外処理
12: [springで例外処理] 使われていないHttpMethodでリクエストが来た時の処理・サーバー内でエラーが起きた時の処理
13: [springで例外処理] TODOフォームのバリデーション1: 文字数制限・@Validatedを使うためのGradleの更新

Gradleに新しい依存性を追加する

今回のアプリケーションのSpringはVersion2.3.0.RELEASEを使用しています。

2.3のRelease Noteを見ると@Validated@Sizeといった今回使う予定のアノテーションをデフォルトで使用する事ができません。

ですので上記リンクの内容に従ってbuild.gradleの依存性の部分にvalidation関係のものを追加します。

build.graleに追記

build.gradle
dependencies {
    //略
    implementation 'org.springframework.boot:spring-boot-starter-validation'
    }

この依存性を追加する事でバリデーション関係のアノテーションが使えるようになります。

build.gradleの更新

追加しただけでは反映されないのでgradleの更新を行います。下記画像を参考にしてください。

無事更新が終わったら次はコントローラの編集・TODOの投稿につかうフォームデータクラスの確認などを行っていきます。

バリデーションを行う

投稿内容の確認

まずは今回のTODOのバリデーション内容を確認します。

  1. 投稿内容は1文字以上30文字以内である
  2. 空文字は認めない
  3. 同じ内容の投稿は認めない

以上3点となります。今回は1文字以上30文字以内である場合をバリデーションしようと思います。

フォームデータクラスの確認

java/com/example/todo/TodoForm.java
package com.example.todo;
import com.sun.istack.NotNull;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.Size;
import java.time.LocalDate;

@Data
public class TodoForm {
    private long Id;

    @NotNull
    @Size(min = 1, max =30)
    private String title;

    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate deadline;

    private boolean status;
}

こんな形です。
@NotNulltitle(投稿内容)にnullを許容しないものです。
@sizeは最小と最大文字をしていすることができます。

コントローラクラスの編集

    @PostMapping("/register")
    public String register(@Validated @ModelAttribute TodoForm formData, BindingResult error, RedirectAttributes attributes) {
        if(error.hasErrors()) {
            attributes.addFlashAttribute("errorMessages", error);
            return "redirect:/top";
        }
        todoService.setTodo(formData);
        return "redirect:/top";
    }

@Validated, BindingResult, RedirectAttributesを追加しました。

@Validatedは投稿内容がTodoFormのバリデーション内容をチェックしてくれるアノテーションです。
これでNullをチェックしたり文字数を判別する事ができます。

仮にバリデーションに引っかかる場合はBindingResultクラスの変数errorにエラー内容が保存されます。

RedirectAttributesはフロントに返す用に使われています。

if(error.hasErrors())...の部分でerrorにエラー内容が保存されている場合(つまりバリデーションに引っかかっている)の条件分岐です。

error変数errorMessagesとしてフロントに渡しています。

フロントにエラー内容を表示させる

header直下に下記を追加します。

resources/templates/top.html
<!--    エラーメッセージ表示領域-->
<th:block th:if="${errorMessages}">
  <th:block th:each="error : ${errorMessages.getAllErrors()}">
     <div class=" w-75 h-auto my-1 mx-auto pt-5">
        <p class="text-center text-danger" th:text="${error.defaultMessage}"></p>
     </div>
  </th:block>
</th:block>

先ほどエラーがある時にerrorMessagesを渡すと書きましたがThymeleafの昨日でif文を追加してエラーメッセージがあるかどうか判定しています。

エラーがある場合はeach文でそれらを全て一つずつ表示します。

th:text="${error.defaultMessage}"とありますがエラーメッセージの内容は.defaultMessageで取得する事ができます。

試しに30文字以上の文字を入力すると下記のようなメッセージが表示されます。

今回は触れませんがこのメッセージは任意のものに変える事もできます!

次回の記事では残り2つのバリデーションについて触れていきます!