こんにちは。ゆうせいです。
今回は、新人エンジニアの方に向けて、Spring BootとThymeleafを使った「都道府県を選んで送信するフォーム」について、実際のコードを使って解説していきます。
実際のコードの掲載
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を確認 | 
| 選択状態がリセットされる | selectedPrefがnullになっている | POST時に値を渡せているかチェック | 
| フォームが送信されない | method="post"がない | formタグの属性を確認 |