【8/27まで】Udemyの人気コースが今なら1,200円から!!

【Spring Boot】単項目チェックしてエラーメッセージを表示する(@Validated)

【Spring Boot】単項目チェックしてエラーメッセージを表示する(@Validated)

この記事では、@Validatedを使用して入力チェックを行う方法について解説します。

プロジェクトの作成

VSCodeでSpringBootのMavenプロジェクトを作成します。
手順は以下の記事を参照。
【Windows版】VSCodeで始めるSpringBoot(Mavenプロジェクト編) 【Windows版】VSCodeで始めるSpringBoot(Mavenプロジェクト編)

プロジェクト作成時、以下の5つの依存関係を選択します。5個目のvalidationを選択しておかないと入力チェックができないので注意してください。

  • Spring Boot DevTools
  • Spring Web
  • Thymeleaf
  • Lombok
  • validation

用意するソース

SpringBootで新規プロジェクトを作成したら、以下のソースを用意して実行できる状態にします。

コントローラー(BaseController.java)

com.example.demo4.controlloer直下に以下の内容でBaseController.javaを作成します。

BaseController.java

package com.example.demo4.controlloer;

import com.example.demo4.model.Otoiawase;

import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;

@Controller
public class BaseController {

    @GetMapping("/")
    public String home(@ModelAttribute Otoiawase otoiawase){
      return "form";
    }

    @PostMapping("/")
    public String result(@Validated 
                        @ModelAttribute Otoiawase otoiawase,
                        BindingResult result){
        if(result.hasErrors()){
            return "form";
        }
        return "result";
    }
}
解説
@Validatedアノテーション
入力チェックを行います。チェックの結果は
BindingResult resultに代入され、エラーが存在する場合はresult.hasErrors()trueを受け取れます。

モデル(Otoiawase.java)

com.example.demo4.model直下に以下の内容でOtoiawase.javaを作成します。

Otoiawase.java

package com.example.demo4.model;

import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;

import org.springframework.format.annotation.NumberFormat;

import lombok.Data;

@Data
public class Otoiawase {

    /**
     * <p>項目名:氏名</p>
     * <p>必須入力かつ、最大20文字まで</p>
     */
    @NotBlank
    @Size(max=20)
    private String name;

    /**
     * <p>項目名:メールアドレス</p>
     * <p>条件:必須入力かつ、最大64文字まで</p>
     */
    @NotBlank
    @Email
    @Size(max=64)
    private String email;

    /**
     * <p>項目名:電話番号</p>
     * <p>条件:必須入力かつ、数値のみ、最大12文字まで</p>
     */
    @NotBlank
    @NumberFormat
    @Size(max=12)
    private String tel;

    /**
     * <p>項目名:内容</p>
     * <p>条件:必須入力かつ、最大200文字まで</p>
     */
    @NotBlank
    @Size(max=200)
    private String contents;
}
解説
@NotBlankアノテーション
以下のいずれかの場合にエラーになります。
  • 文字列がNULL
  • 文字列が空文字
  • 文字列が半角スペース

@Sizeアノテーション
文字列の長さが指定した範囲を超えた場合、エラーになります。
例えば@Size(max=20)とした場合、21字以上入力するとエラーになります。
@Emailアノテーション
不正なメールアドレス(書式が正しくない)場合、エラーになります。

遷移元ページ(form.html)

resources\templates直下に以下の内容でform.htmlを作成します。

form.html

<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>form</title>
<script type="text/javascript"></script>
<link th:href="@{/webjars/bootstrap/css/bootstrap.min.css}" rel="stylesheet">
</head>
<body class="bg-light">
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-5">
                <h2 th:text="#{contents}"></h2>
                <form th:action="@{/}" th:object="${otoiawase}" method="post" novalidate>
                    <div class="mb-3">
                        <label for="name" th:text="#{name}"></label>
                        <input type="text" class="form-control" th:errorclass="is-invalid" placeholder="taro" th:field="*{name}">
                        <div class="invalid-feedback" th:errors="*{name}"></div>
                    </div>
                    <div class="mb-3">
                        <label for="email" th:text="#{email}"></label>
                        <input type="email" class="form-control" th:errorclass="is-invalid" placeholder="taro@example.com" th:field="*{email}">
                        <div class="invalid-feedback" th:errors="*{email}"></div>
                    </div>
                    <div class="mb-3">
                        <label for="tel" th:text="#{tel}"></label>
                        <input type="number" class="form-control" th:errorclass="is-invalid" placeholder="0123456789" th:field="*{tel}">
                        <div class="invalid-feedback" th:errors="*{tel}"></div>
                    </div>
                    <div class="mb-3">
                        <label for="contents" th:text="#{contents}"></label>
                        <textarea class="form-control" row="5" th:errorclass="is-invalid" placeholder="Hello."th:field="*{contents}"></textarea>
                        <div class="invalid-feedback" th:errors="*{contents}"></div>
                    </div>
                    <button class="btn btn-primary btn-lg" type="submit" th:text="#{register}"></button>
                </form>
            </div>
        </div>
    </div>
    <script th:src="@{/webjars/bootstrap/js/bootstrap.bundle.min.js}"></script>
</body>
</html>

遷移先ページ(result.html)

resources\templates直下に以下の内容でresult.htmlを作成します。

result.html

<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>result</title>
<script type="text/javascript"></script>
<link th:href="@{/webjars/bootstrap/css/bootstrap.min.css}" rel="stylesheet">
</head>
<body>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-5">
                <h4 class="border-bottomy-3" th:text="#{contents}"></h4>
                <p class="text-danger" th:text="#{confirmMessage}"></p>
                <div th:object="${otoiawase}">
                    <div class="mb-3">
                        <label for="name" th:text="#{name}"></label>
                        <input type="text" class="form-control" th:field="*{name}" disabled>
                    </div>
                    <div class="mb-3">
                        <label for="email" th:text="#{email}"></label>
                        <input type="email" class="form-control" th:field="*{email}" disabled>
                    </div>
                    <div class="mb-3">
                        <label for="tel" th:text="#{tel}"></label>
                        <input type="number" class="form-control" th:field="*{tel}" disabled>
                    </div>
                    <div class="mb-3">
                        <label for="contents" th:text="#{contents}"></label>
                        <textarea class="form-control" row="3" th:field="*{contents}" disabled></textarea>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <script th:src="@{/webjars/bootstrap/js/bootstrap.bundle.min.js}"></script>
</body>
</html>

プロパティファイル(messages_ja.properties)

resources直下に以下の内容でmessages_ja.propertiesを作成します。

messages_ja.properties

contents = お問い合わせ欄
name = 名前
email = メールアドレス
tel = 電話番号
register = 登録
confirmMessage = 以下の内容で登録しました。

上記を作成したらresources直下にmessages.propertiesという名前の空ファイルも作成しておきます。

設定ファイル(pom.xml)

pom.xml

        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>5.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>webjars-locator-core</artifactId>
        </dependency>
解説
Bootstrapを使うために、pom.xmlのdependenciesの配下に上記2つのdependencyを指定します。
webjarsというライブラリを使うと、Bootstrapなどの依存関係をMavenで管理できるようになります。
webjars-locator-coreというライブラリを使うと、BootstrapなどをHTMLで読み込む際にバージョン情報などを記載しなくても済むようになります。

実行結果

上記のソースを実行してブラウザでhttp://localhost:8080/にアクセスすると以下の画面が表示されます。これは遷移元ページ(form.html)が表示されています。


このまま何も入力せずに「登録」ボタンを押すと、以下のようにエラーメッセージが表示されます。

続いて、以下のようにエラーにならない入力内容を考えてみます。

この内容で「登録」ボタンを押すと、次のように遷移先ページ(result.html)に遷移して入力内容が登録されたことが確認できました。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です