📚

Spring bootでThymeleafを利用する

2023/02/20に公開

前提

Spring bootプロジェクトの新規作成にて行ったプロジェクトファイルを使って行います。
もしSpring bootのプロジェクトを作成してない人は、前の章に戻り作成を行なってください。

Thymeleaf(タイムリーフ)とは?

Thymeleafとは、JavaのWebアプリケーションで利用できるテンプレートエンジンの一つで、HTMLやXML、テキストなどのテンプレートを処理し、ビューとしてクライアントにレンダリングすることができます。

Spring Frameworkとの親和性が高く、Spring Bootと組み合わせることで、簡単かつ効率的にWebアプリケーションを構築することが可能です。

Thymeleafを利用する

実際にThymeleafを利用していきます。

簡単なViewを作成して表示する

Hello Thymeleaf Viewを表示するだけのページを作っていきます。
まずページを表示する際にリクエスト処理を行うためのコントローラを作っていきます。
現在のプロジェクトに新たにcontrollerという名前でパッケージを作り、その中にHelloController.javaという名前のクラスを作成します。
ディレクトリー構成としては以下になります。

.
├── HELP.md
~~~~~~ 省略 ~~~~~~~
└── src
    └── main
        └──java
            └── nogulab
                └── com
                    └── sample
                        ├── SampleApplication.java
                        └── controller ← (今回新規追加するパッケージ)
                            └── HelloController.java ← (今回追加するコントローラクラス)

コントローラークラス

HelloController.java のコードは以下になります

package nogulab.com.sample.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HelloController {
    @GetMapping("view")
    public String helloView(){
        // 戻り値は「ビュー名」を返す
        return "hello";
    }
}

コントローラークラスについて説明を行なっていきます。
@Controllerアノテーションは、このクラスがSpringのコンポーネントであることを示してます。Springコンテナにこのクラスのインスタンスが登録され、Springが管理するBeanとなります。
@GetMappingアノテーションは、HTTP GETリクエストを処理するメソッドであることを示してます。
引数にはリクエストURLを指定します。上記の例では、/viewというURLのGETリクエストを処理するメソッドになります。
メソッドの戻り値は、ビュー名を返します。ビュー名は、ビューテンプレートの名前であり、テンプレートエンジンが指定されたビューがレンダリングされます。

ビューテンプレート

ディレクトリー構成としては以下になります。

.
├── HELP.md
~~~~~~ 省略 ~~~~~~~
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
    └── main
        └── resources
            ├── application.properties
            ├── static
            └── template
                └── hello.html ← (今回新規追加するビューテンプレートとなるhtmlファイル)

ビューテンプレートとなるhello.htmlのコードは以下になります

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!-- 追記記述 -->
<h1>Hello Thymeleaf View!!!</h1>
</body>
</html>

試しにアクセスしてみる

以上のファイルを作成し終えたら、Spring Boot applicationを実行しお使いのブラウザからhttp://127.0.0.1:8080/viewにアクセスすると以下のように表示されると思います。

テンプレートとしての機能を試してみる

先ほどはシンプルにhtmlを表示するもを用意しましたが、今回はtwitterのようなツイートを表示するテンプレートviewを用意し、そこにコントローラから変数を渡し表示するといったものを実装してみます。

Tweetオブジェクトの作成

Tweetオブジェクトは、ツイートの情報を格納するためのオブジェクトです。このオブジェクトには、ツイートの本文、投稿時間、ユーザー名、ユーザーIDなどの情報を含んでいます。

Tweet.java
package nogulab.com.sample.controller;

import java.time.LocalDateTime;

public class Tweet {
    private String text;
    private String createdAt;
    private String userName;
    private String accountId;

    public Tweet(String text, String createdAt, String userName, String accountId) {
        this.text = text;
        this.createdAt = createdAt;
        this.userName = userName;
        this.accountId = accountId;
    }

    public String getUserName() {
        return userName;
    }

    public String getText() {
        return text;
    }

    public String getCreatedAt() {
        return createdAt;
    }

    public String getAccountId() {
        return accountId;
    }
}

コントローラの作成

コントローラではTweetオブジェクトを作成し、それをModelオブジェクトに追加します。
Modelオブジェクトは、コントローラーからビューに渡され、ビューでTweetオブジェクトの要素を表示します。

TweetController.java
package nogulab.com.sample.controller;

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

@Controller
public class TweetController {
    @GetMapping("view")
    public String helloView(Model model){
        Tweet tweet = new Tweet(
                "This is a tweet message.",
                "12h ago",
                "Nogu.d",
                "@nogud626"
        );
        model.addAttribute("tweet", tweet);
        // 戻り値は「ビュー名」を返す
        return "tweet";
    }
}

viewとなるテンプレートの作成

Tweetオブジェクトの要素を表示するためのThymeleafテンプレートを作成していきます。

HTML要素内にth:プレフィックスをつけた属性を用いることで、Tweetオブジェクトの各要素をテンプレート内で参照することができるようになります。

tweet.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>ツイート詳細</title>
    <link th:href="@{/css/style.css}" rel="stylesheet" />
</head>
<body>
<div class="container">
    <div class="tweet">
        <img class="avatar" src="https://via.placeholder.com/50x50" alt="User Avatar">
        <div class="tweet-content">
            <div class="tweet-header">
                <h3 class="name" th:text="${tweet.userName}"></h3>
                <span class="username" th:text="${tweet.accountId}"></span>
                <span class="timestamp" th:text="${tweet.createdAt}"></span>
            </div>
            <p class="message" th:text="${tweet.text}"></p>
        </div>
    </div>
</div>
</body>
</html>

viewのデザインを管理するCSSの作成

style.css
.tweet {
    display: flex;
    margin: 10px 0;
    padding: 10px;
    background-color: #fff;
    width: 350px;
    border-radius: 10px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
}

.avatar {
    width: 50px;
    height: 50px;
    margin-right: 10px;
    border-radius: 50%;
}

.tweet-header {
    display: flex;
    align-items: center;
}

.name {
    margin-right: 5px;
    font-size: 16px;
    font-weight: bold;
}

.username {
    margin-right: 5px;
    color: gray;
}

.timestamp {
    color: gray;
}

.message {
    margin-top: 10px;
    font-size: 14px;
    line-height: 1.5;
}

全体のディレクトリー構成

└── src
    └── main
        ├── java
        │   └── nogulab
        │       └── com
        │           └── sample
        │               ├── SampleApplication.java
        │               └── controller
        │                   ├── Tweet.java ← (今回追加)
        │                   └── TweetController.java ← (今回追加)
        └── resources
            ├── application.properties
            ├── static
            │   └── css
            │       └── style.css ← (今回追加)
            └── templates
                └── tweet.html ← (今回追加)

表示の確認

Spring Boot applicationを実行しお使いのブラウザからhttp://127.0.0.1:8080/viewにアクセスすると以下のように表示されると思います。

複数の要素をテンプレートで表示する

controllerとviewをそれぞれ以下のように修正していきます。

TweetController.java
package nogulab.com.sample.controller;

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

import java.util.ArrayList;
import java.util.List;

@Controller
public class TweetController {
    @GetMapping("view")
    public String helloView(Model model){
        List<Tweet> tweets = new ArrayList<>();

        tweets.add(new Tweet(
                "This is the first tweet.",
                "12h ago",
                "Nogu.d",
                "@nogud626"
        ));

        tweets.add(new Tweet(
                "This is the second tweet.",
                "2h ago",
                "John Doe",
                "@johndoe"
        ));

        model.addAttribute("tweets", tweets);
        // 戻り値は「ビュー名」を返す
        return "tweet";
    }
}
tweet.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>ツイート詳細</title>
    <link th:href="@{/css/style.css}" rel="stylesheet" />
</head>
<body>
<div class="container">
    <div th:each="tweet : ${tweets}" class="tweet">
        <img class="avatar" src="https://via.placeholder.com/50x50" alt="User Avatar">
        <div class="tweet-content">
            <div class="tweet-header">
                <h3 class="name" th:text="${tweet.userName}"></h3>
                <span class="username" th:text="${tweet.accountId}"></span>
                <span class="timestamp" th:text="${tweet.createdAt}"></span>
            </div>
            <p class="message" th:text="${tweet.text}"></p>
        </div>
    </div>
</div>
</body>
</html>

表示の確認

Spring Boot applicationを実行しお使いのブラウザからhttp://127.0.0.1:8080/viewにアクセスすると以下のように表示されます。

Discussion