【Spring Boot】Thymeleafでビューを作成する基本

Java

こんにちは、かつコーチです。

前回、@GetMapping@PostMappingでリクエストを受け取る方法を見てきました。
今回は、Controllerが選んだ画面を実際に組み立てるThymeleafの基本を解説します。
JSPに代わってSpring Bootの標準テンプレートエンジンとして採用されているThymeleafは、HTMLファイルそのものとして開いても崩れない「自然なテンプレート」が特徴です。

Thymeleafとは?

テンプレートエンジンの役割

テンプレートエンジンとは、HTMLの雛形にサーバー側のデータを埋め込んで、最終的なHTMLを生成する仕組みです。
ControllerがModelに詰めたデータを、Thymeleafのテンプレートファイル(.html)が受け取り、動的なHTMLとして出力します。

@Controller
public class GreetingController {

    @GetMapping("/greeting")
    public String greeting(Model model) {
        model.addAttribute("message", "こんにちは、かつコーチです。");
        return "greeting"; // templates/greeting.html を使う
    }
}

なぜThymeleafが標準なのか

Thymeleafの最大の特徴は、th:textのような独自の属性を通常のHTML属性として追加するだけなので、ブラウザでそのまま開いても普通のHTMLとして表示できる点です。
JSPのように専用のタグライブラリで構文が大きく変わることがなく、デザイナーとエンジニアの分業がしやすいという利点があります。
Spring Bootではspring-boot-starter-thymeleafを依存関係に追加するだけで、src/main/resources/templates配下の.htmlファイルが自動的にテンプレートとして認識されます。

基本の書き方・実装手順

手順1:変数を表示する(th:text)

Modelに詰めた値をHTML内に表示するには、th:text属性を使います。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>挨拶画面</title>
</head>
<body>
    <h1 th:text="${message}">ここはダミーの見出しです</h1>
</body>
</html>

th:text="${message}"は、Controllerでmodel.addAttribute("message", ...)した値を、<h1>タグの中身として描画します。
元々書かれていた「ここはダミーの見出しです」というテキストは、実行時にはmessageの値に置き換わります。
このダミーテキストのおかげで、ブラウザで直接ファイルを開いてもレイアウト崩れを確認できるのが、Thymeleafならではの利点です。

手順2:一覧をループで表示する(th:each)

一覧画面のように、リストの中身を繰り返し表示したい場合はth:eachを使います。

@GetMapping("/users")
public String list(Model model) {
    List<String> names = List.of("田中", "佐藤", "鈴木");
    model.addAttribute("names", names);
    return "users/list";
}
<ul>
    <li th:each="name : ${names}" th:text="${name}">サンプル</li>
</ul>

th:each="name : ${names}"は、namesリストの要素を1つずつnameという変数に入れながら、<li>タグを繰り返し生成します。

手順3:条件分岐で表示を切り替える(th:if)

ログイン状態など、条件によって表示を変えたい場合はth:ifth:unlessを使います。

<p th:if="${names.isEmpty()}">ユーザーが登録されていません。</p>
<p th:unless="${names.isEmpty()}">登録者数:<span th:text="${names.size()}"></span>人</p>

つまずきやすい設定・注意点

リンクやフォームのURLを組み立てる際は、文字列連結ではなく@{}というURL式を使います。

<a th:href="@{/users/{id}(id=${user.id})}">詳細を見る</a>

こうしておくと、Spring Bootのコンテキストパス設定が変わった場合でもリンクが自動的に追従してくれます。

よくあるつまずきポイント・エラー対処

templatesフォルダの配置を間違える

初心者が最もつまずきやすいのが、テンプレートファイルの配置場所です。

❌ Before
src/main/resources/greeting.html

Controllerでreturn "greeting"としているのに、上記のようにtemplatesフォルダの外にファイルを置いてしまうと、以下のエラーになります。

org.thymeleaf.exceptions.TemplateInputException:
Error resolving template [greeting], template might not exist
or might not be accessible by any of the configured Template Resolvers

筆者もプロジェクトの初期にファイルをresources直下に作ってしまい、このエラーメッセージを見ても「テンプレートが存在しない」の意味が最初はピンと来ませんでした。
実際には、Spring Bootの標準設定ではtemplatesフォルダの中しか探しに行かないため、フォルダを1つ間違えただけでこのエラーになります。

✅ After
src/main/resources/templates/greeting.html

templatesフォルダの直下(またはサブフォルダ)にHTMLを置くことで、Controllerのreturn値とテンプレートが正しく紐づきます。

応用・一歩先の使い方

複数の画面で共通するヘッダーやフッターは、Thymeleafのレイアウト機能th:insertth:replacethymeleaf-layout-dialect)を使って部品化できます。
画面数が増えてくると、共通パーツをコピーして回るのは保守性が下がるため、早い段階でレイアウトの共通化を意識しておくと後々の修正が楽になります。

まとめ

この記事のポイント

  • ThymeleafはHTMLとして開いても崩れない「自然なテンプレート」が特徴
  • th:textで変数表示、th:eachで繰り返し、th:ifth:unlessで条件分岐を行う
  • URLは文字列連結ではなく@{}のURL式で組み立てる
  • テンプレートファイルは必ずsrc/main/resources/templates配下に置く

次に読むべき記事

画面が作れるようになったら、次は「コンストラクタインジェクションと@Autowiredの使い分け」で、DIの実装方法をより実践的に理解していきましょう。

タグ: Spring Boot, 初心者向け, フレームワーク基礎

タイトルとURLをコピーしました