Spring Boot フォーム関連のサンプルコード (Thymeleaf)
[最終更新] (2019/05/31 01:30:47)
最近の投稿
注目の記事

概要

Spring Boot のテンプレートエンジンとしては、こちらで使用方法を把握した Thymeleaf が有名です。本ページでは、フォーム関連の処理について、基本的なサンプルコードをまとめます。Rails におけるビューヘルパーや、フォーム入力値のバリデーションに相当する機能です。

公式ドキュメント

サンプルプロジェクト構成

.
|-- build.gradle
|-- gradle
|   `-- wrapper
|       |-- gradle-wrapper.jar
|       `-- gradle-wrapper.properties
|-- gradlew
|-- gradlew.bat
`-- src
    `-- main
        |-- java
        |   `-- hello
        |       |-- Application.java
        |       |-- Greeting.java
        |       `-- GreetingController.java
        `-- resources
            `-- templates
                |-- greeting.html
                `-- result.html

build.gradle および Application.java については、こちらのページと同じ内容です。

Java ソースコード

Greeting.java

コントローラとビューで値のやり取りを行うための、入れ物となるクラスです。idcontent は HTML ファイル内の form 内の input に対応しています。

package hello;

public class Greeting {

    private long id;
    private String content;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

GreetingController.java

こちらのページにおける @RequestMapping(path = "/greeting", method = RequestMethod.GET) に相当するアノテーション @GetMapping("/greeting") を利用しています。@GetMapping 側のアクションについては、Model model に空の Greeting オブジェクトを格納して greeting ビューで利用しています。@PostMapping 側のアクションについては、@ModelAttribute が付与された Greeting greeting に POST されたパラメータが自動で格納されており、result ビューで利用されます。

package hello;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;

@Controller
public class GreetingController {

    @GetMapping("/greeting")
    public String greetingForm(Model model) {
        model.addAttribute("greeting", new Greeting());
        return "greeting";
    }

    @PostMapping("/greeting")
    public String greetingSubmit(@ModelAttribute Greeting greeting) {
        // return "greeting"; // 同じビューを使い回すこともできます。
        return "result";
    }
}

HTML ファイル

greeting.html

こちらのページにも記載した @{} を利用してリンクすることで、例えばアプリケーション全体が /myapp といったプレフィックス以下で動作する場合にも対応できます。また、th:field はモデルのメンバ変数と input をバインドするための設定です。

Relative URLs starting with / (eg: /order/details) will be automatically prefixed by the application context name.
http://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#link-urls

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
  <title>Getting Started: Handling Form Submission</title>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
  <h1>Form</h1>
  <form action="#" th:action="@{/greeting}" th:object="${greeting}" method="post">
    <p>Id: <input type="text" th:field="*{id}" /></p>
    <p>Message: <input type="text" th:field="*{content}" /></p>
    <p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
  </form>
</body>
</html>

result.html

POST された値を Thymeleaf の記法にしたがって設定して表示します。ここまで内容は http://localhost:8080/greeting にアクセスして動作確認できます。

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
  <title>Getting Started: Handling Form Submission</title>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
  <h1>Result</h1>
  <p th:text="'id: ' + ${greeting.id}" />
  <p th:text="'content: ' + ${greeting.content}" />
  <a href="/greeting">Submit another message</a>
</body>
</html>

チェックボックス

チェックボックスが一つの場合

input タグには id が自動で付与されて、th:for から参照されます。

greeting.html

<div>
  <label th:for="${#ids.next('admin')}">Admin</label>
  <input type="checkbox" th:field="*{admin}" />
</div>

Greeting.java

private boolean isAdmin;

public boolean isAdmin() {
    return isAdmin;
}

public void setAdmin(boolean isAdmin) {
    this.isAdmin = isAdmin;
}

チェックボックスが複数の場合

先程の例の #ids.next() ではなく #ids.prev() を用いると、label タグを input タグの後ろに設置できます。また、先程の例の isAdmin と異なり、今回の features は boolean ではないため、複数チェックボックスに対してそれぞれ th:value で値を設定しています。

greeting.html

<ul>
  <li th:each="feat : ${allFeatures}">
    <input type="checkbox" th:field="*{features}" th:value="${feat}" />
    <label th:for="${#ids.prev('features')}" 
           th:text="${feat}">feature label</label>
  </li>
</ul>

Greeting.java

private List<String> features;

public List<String> getFeatures() {
    return features;
}

public void setFeatures(List<String> features) {
    this.features = features;
}

GreetingController.java

@GetMapping("/greeting")
public String greetingForm(Model model) {
    model.addAttribute("greeting", new Greeting());
    model.addAttribute("allFeatures", Arrays.asList("xxx", "yyy"));
    return "greeting";
}

@PostMapping("/greeting")
public String greetingSubmit(@ModelAttribute Greeting greeting, Model model) {
    greeting.setId(greeting.getId() + 1);
    model.addAttribute("allFeatures", Arrays.asList("xxx", "yyy"));
    return "greeting";
}

ラジオボタン

ラジオボタンは、複数チェックボックスの場合と似た記法になります。ただし、モデルが保持する値は単数です。

greeting.html

<ul>
  <li th:each="feat : ${allFeatures}">
    <input type="radio" th:field="*{feature}" th:value="${feat}" />
    <label th:for="${#ids.prev('feature')}" th:text="${feat}">feature label</label>
  </li>
</ul>

Greeting.java

private String feature;

public String getFeature() {
    return feature;
}

public void setFeature(String feature) {
    this.feature = feature;
}

GreetingController.java

(複数チェックボックスの場合と同じであるため、省略。)

セレクトボックス

セレクトボックスはラジオボタンとほぼ同じ構造になります。以下の例において、Greeting.java と GreetingController.java はラジオボタンと同じであるため省略します。

greeting.html

<select th:field="*{feature}">
  <option th:each="feat : ${allFeatures}" 
          th:value="${feat}" 
          th:text="${feat}"></option>
</select>

基本的なフォームバリデーション

Validating Form Input に記載の org.hibernate:hibernate-validator は、org.springframework.boot:spring-boot-starter-thymeleaf が依存するため build.gradle に明記する必要はありません。依存関係は以下のコマンドで確認できます。

./gradlew dependencies

この続きが気になる方は

Spring Boot フォーム関連のサンプルコード (Thymeleaf)

残り文字数は全体の約 49 %
tybot
100 円
関連ページ
    概要 Rails における ERB と同様に、Spring Boot でもテンプレートエンジンを利用できます。今回は特に Thymeleaf (タイムリーフ) のサンプルコードを、こちらのページで構築した環境をもとにまとめます。 公式ドキュメント Serving Web Content with Spring MVC