Thymeleafタグの利用

Thymeleafタグ

Thymeleafは、HTMLテンプレートに特殊なタグを埋め込むことでき、プレースホルダーとしてJavaのデータオブジェクトと結びつけることができます。

Thymeleaf Docs(公式サイト)

利用できるタグは公式サイトで確認できます。

Thymeleaf Docs

thタグ

HTMLタグのプロパティに th: で始まる専用タグを利用することで、用途に応じたレンダリングができます。

<タグ名 th:xxx></タグ名>

以下は、よく使用されるThymeleafのタグです。

th:text

テキスト要素の値を設定します。

<p th:text="${user.name}">John Doe</p>

th:if

条件式がtrueのとき、要素を表示します。

<p th:if="${user.isAdmin}">This user is an administrator</p>

th:unless

条件式がunlessのとき、要素を表示します。

<p th:unless="${user.isBlocked}">This user is not blocked</p>

th:each

リストや配列の要素を繰り返し処理します。

<ul>
    <li th:each="book : ${books}" th:text="${book.title}"></li>
</ul>

th:href

リンクのURLを設定します。

<a th:href="@{/books/{id}(id=${book.id})}" th:text="${book.title}"></a>

th:src

画像のURLを設定します。

<img th:src="@{/images/book.png}" alt="Book">

${ }

${ } は、テンプレート内で変数や式を評価してその結果を表示します。Javaオブジェクトのデータや、演算、条件分岐などの処理結果をHTMLに埋め込めます。

変数の表示

<p>Welcome, ${user.name}!</p>

数値の演算

<p>Total: ${num1 + num2}</p>

条件分岐

<p th:text="${user.age >= 18 ? '成人' : '未成年'}">年齢を表示</p>

*{ }

*{} は、オブジェクトのプロパティにアクセスするために使用されます。特にリンクやフォームなどで頻繁に使用されます。

aリンクのURLの一部に変数設定
<a th:href="@{/users/{id}(id=*{user.id})}">User Details</a>
forEachで繰り返し「id」に変数設定
<tr th:each="article : ${articles}" id=*{article.id}>
    ...
</tr>

@{ }

@{ } はURLやリンク先を簡単に定義するための構文で、絶対パスや相対パスを意識せずに動的なURLを簡単に生成できます。

URLに変数を埋め込む

URLにJavaで生成したオブジェクト名を埋め込むには、( ) の中に変数を定義し、 { } で文字列と変数を連結します。

<a href="@{xxxx{変数}(変数=${オブジェクト})">リンク1</a>

以下は、article.idを変数idに代入して、URL生成した例です。

<a href="@{/article/{id}(id=*{article.id})">リンク1</a>

#{ }

#{ } は、国際化対応(i18n)のメッセージを取得に使用されます。テンプレート内で多言語対応のメッセージを表示できます。

CSSファイル

ThymeleafタグでCSSファイルを外部読み込みします。

CSSファイル作成

resouces/static/ に「css」フォルダと「style.css」ファイルを作成します。

外部CSSリンク

テンプレートファイルのheadタグに th:hrefプロパティで「/css/style.css」を読み込みます。

<link rel="stylesheet" th:href="@{/css/style.css}">
templates/home/sample.html
...
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My News</title>
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
  <link rel="stylesheet" th:href="@{/css/style.css}">
</head>
...

画像追加

th:src

imgタグのth:srcプロパティで、画像ファイル「images/tokyo_station.jpg」を読み込みます。

<img th:src="@{images/tokyo_station.jpg}">
templates/home/sample.html

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My News</title>
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
  <link rel="stylesheet" th:href="@{/css/style.css}">
</head>

<body>
  <main class="container">

    <div>
      <h2>最新ニュース</h2>
      <div>
        <h3>ニュースタイトル1</h3>
        <p>
          <span>2023/07/01 13:15</span>
        </p>
        <div class="mb-3">
          <img src="/images/tokyo_station.jpg" width="500">
        </div>
      </div>
    </div>

  </main>
</body>

</html>
結果

リンク追加

コントローラー作成

ArticleControllerコントローラー作成

ArticleControllerコントローラーを作成します。

controllers/ArticleController.java
package com.example.demo.controllers;

import org.springframework.stereotype.Controller;

@Controller
public class ArticleController {

}

ArticleControllerコントローラー作成

アクションメソッドdetail() を追加し、マッピングはGETリクエスト /article/{id} とします。また、テンプレートarticle/sample.htmlをレンダリングします。

controllers/ArticleController.java
@Controller
public class ArticleController {
    // 「/article/xx」でアクセスし、任意の値「xx」が「id」に代入される
    @GetMapping("/article/{id}")
    // アクションメソッド
    public String detail() {
        // HTMLテンプレートのレンダリング
        return "article/sample";
    }
}

マッピングの変数

マッピングのURIで、{ } で任意の値を指定できます。

// 「/article/xx」でアクセスし、任意の値「xx」が「id」に代入される
@GetMapping("/article/{id}")

テンプレート作成

テンプレートファイル「article/sample.html」を作成します。

templates/article/sample.html
<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My News</title>
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
  <link rel="stylesheet" th:href="@{/css/style.css}">
</head>

<body>
  <main class="container">
    <div>
      <h2>ニュース</h2>
      <div class="mb-3">
        <div>
          <h3>ニュースタイトル1</h3>
          <p>
            <span>2023/07/01 13:15</span>
          </p>
          <div class="mb-3">
            <img src="/images/tokyo_station.jpg" width="500">
          </div>
          <p>
            ニュース記事です。
          </p>
        </div>
      </div>

    </div>
  </main>
</body>

</html>

ブラウザで確認

http://localhost:8080/article/xx でアクセスするとページが表示されます。

結果

@PathVariable

@PathVariableはURLに含まれるパス変数(Path Variable)を取得するために使用されるアノテーションです。RESTfulなアーキテクチャでは、URLにパス変数を含めるリクエストが一般的です。

@PathVariableの利用方法

コントローラーメソッドの引数を @PathVariableで追加し、{変数} と一致させます。

変数名を自動指定
@GetMapping("/xxxx/{変数}")
public String method(@PathVariable データ型 変数) {

}
変数名を明示的に指定
@GetMapping("/xxxx/{変数}")
public String method(@PathVariable("パス変数名") データ型 変数) {

}

パス変数の取得

パス変数をLong型で取得

URLパス /article/{id} のパス変数「id」を、Long型で取得します。

controllers/ArticleController.java
@Controller
public class ArticleController {

    @GetMapping("/article/{id}")
    public String detail(@PathVariable("id") Long id) {
        System.out.println("article id: " + id);
        return "article/sample";
    }

}

コンソールで確認

http://localhost:8080/article/xx でアクセスして、コンソールでパス変数を確認します。

  • 「xx」は数値以外を指定するとランタイムエラーになります。
結果例
article id: 1

URLリンク設定

aタグのth:hrefプロパティで、任意の数値をパス変数としたURLリンクを設定します。

<a th:href="@{/article/1}">ニュース1</a>
templates/home/sample.html
<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My News</title>
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
  <link rel="stylesheet" th:href="@{/css/style.css}">
</head>

<body>
  <main class="container">
    <div>
      <h2>最新ニュース</h2>
      <div>
        <h3>ニュースタイトル1</h3>
        <p>
          <span>2023/07/01 13:15</span>
        </p>
      </div>

      <div class="mb-3">
        <img src="/images/tokyo_station.jpg" width="500">
      </div>

      <div>
        <h3>ニュース一覧</h3>
        <ul class="list-group">
          <li class="list-group-item"><a th:href="@{/article/1}">ニュース1</a></li>
          <li class="list-group-item"><a th:href="@{/article/2}">ニュース2</a></li>
          <li class="list-group-item"><a th:href="@{/article/3}">ニュース3</a></li>
        </ul>
      </div>

    </div>
  </main>
</body>

</html>

リンク確認

「/article/」から「/article/xx」にリンクできるか確認してみましょう。

ホーム
/article/xx

Spring超入門