こんにちは。ゆうせいです。

今回は、新人エンジニアの方に向けて、Spring BootThymeleafを使った「都道府県を選んで送信するフォーム」について、実際のコードを使って解説していきます。

実際のコードの掲載

package com.example.demo.controller;

import java.util.List;

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

@Controller
public class ValueController {

    private final List<String> prefectures = List.of("北海道", "東京都", "大阪府", "福岡県");

    @GetMapping("/value")
    public String showForm(Model model) {
        model.addAttribute("prefList", prefectures);
        model.addAttribute("selectedPref", null);
        return "value";
    }

    @PostMapping("/submit")
    public String handleForm(@RequestParam("prefecture") String selectedPref, Model model) {
        model.addAttribute("prefList", prefectures);
        model.addAttribute("selectedPref", selectedPref);
        return "value";
    }
}

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>都道府県選択</title>
</head>
<body>
    <h1>都道府県を選択してください</h1>
    <form th:action="@{/submit}" method="post">
        <select name="prefecture">
            <option value="" disabled selected>選択してください</option>
            <option th:each="pref : ${prefList}"
                    th:value="${pref}"
                    th:text="${pref}"
                    th:selected="${pref == selectedPref}">
            </option>
        </select>
        <button type="submit">送信</button>
    </form>

    <p th:if="${selectedPref != null}">
        選択された都道府県:<span th:text="${selectedPref}"></span>
    </p>
</body>
</html>
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>都道府県選択</title>
</head>
<body>
    <h1>都道府県を選択してください</h1>
    <form th:action="@{/submit}" method="post">
        <select name="prefecture">
            <option value="" disabled selected>選択してください</option>
            <option th:each="pref : ${prefList}"
                    th:value="${pref}"
                    th:text="${pref}"
                    th:selected="${pref == selectedPref}">
            </option>
        </select>
        <button type="submit">送信</button>
    </form>

    <p th:if="${selectedPref != null}">
        選択された都道府県:<span th:text="${selectedPref}"></span>
    </p>
</body>
</html>


コントローラークラスの中身を解説!

クラス名:ValueController

このクラスはコントローラーと呼ばれるもので、ユーザーの操作(リクエスト)を受け取って、どう処理するかを決めています。

@Controller
public class ValueController {

@Controllerというのは、「このクラスはWebリクエストを処理するよ」という合図です。


都道府県のリスト

private final List<String> prefectures = List.of("北海道", "東京都", "大阪府", "福岡県");

ここで定義しているのは、選択肢として表示する都道府県のリストです。


@GetMapping("/value")とは?

@GetMapping("/value")
public String showForm(Model model) {
    model.addAttribute("prefList", prefectures);
    model.addAttribute("selectedPref", null);
    return "value";
}

  • @GetMapping("/value")は「このURLにアクセスされたらこのメソッドを動かすよ」という意味です。
  • Modelというのは、HTMLに値を渡すための箱のようなものです。
  • model.addAttribute(...)で、HTMLから${prefList}として都道府県のリストを使えるようにしています。

@PostMapping("/submit")とは?

@PostMapping("/submit")
public String handleForm(@RequestParam("prefecture") String selectedPref, Model model) {
    model.addAttribute("prefList", prefectures);
    model.addAttribute("selectedPref", selectedPref);
    return "value";
}

  • @PostMapping("/submit")はフォームが送信されたときの処理です。
  • @RequestParam("prefecture")で、送られてきた都道府県を受け取ります。

例えるなら、「誰かが“東京都”って書かれた紙を渡してきたので、それを受け取って、また画面に表示する」といったイメージです。


HTML(Thymeleaf)テンプレートを分解してみよう!

th:action="@{/submit}" とは?

<form th:action="@{/submit}" method="post">

この部分は「フォームの送信先は/submitですよ」という指定です。


th:eachで選択肢を繰り返す!

<option th:each="pref : ${prefList}"
        th:value="${pref}"
        th:text="${pref}"
        th:selected="${pref == selectedPref}">
</option>

  • th:each="pref : ${prefList}"は、「リストに入ってる都道府県をひとつずつ取り出して表示しよう」という意味。
  • th:valueは送信される値
  • th:textは表示される文字
  • th:selectedはその選択肢が選ばれていたかを判断

まるでプリンターが「リストをもらったから順番に印刷していくよ」みたいなイメージです。


実行の流れまとめ(図で確認!)

[ユーザー] → GET /value
   ↓
[サーバー] → HTML表示(フォーム付き)

[ユーザー] → POST /submit(選択肢つき)
   ↓
[サーバー] → HTML表示(選択済みを表示)

よくある間違いとその解決法

ミス内容原因解決方法
都道府県が表示されないprefListが渡されてないmodel.addAttributeを確認
選択状態がリセットされるselectedPrefnullになっているPOST時に値を渡せているかチェック
フォームが送信されないmethod="post"がないformタグの属性を確認

最後までお読みいただきありがとうございます。