1前書き


Thymeleaf

は、HTML、XML、JavaScript、CSS、およびテキストを処理および作成するためのJavaテンプレートエンジンです。

この記事では、Spring MVCアプリケーションのビューレイヤにおける基本的なユースケースとともに、SpringでのThymeleafの使用方法について説明します。

このライブラリは非常に拡張性があり、その自然なテンプレート作成機能により、バックエンドなしでテンプレートをプロトタイプ作成できます。これにより、JSPなどの他の一般的なテンプレートエンジンと比べて開発が非常に速くなります。


2 ThymeleafとSpring

の統合

まず、Springと統合するために必要な設定を見てみましょう。

統合には

thymeleaf-spring

ライブラリが必要です。

Maven POMファイルに以下の依存関係を追加します。

<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf</artifactId>
    <version>3.0.9.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring4</artifactId>
    <version>3.0.9.RELEASE</version>
</dependency>

Spring 4プロジェクトでは、

thymeleaf-spring5

の代わりに

thymeleaf-spring4

ライブラリを使用する必要があります。


SpringTemplateEngine

クラスはすべての設定手順を実行します。このクラスは、Java構成ファイルでBeanとして構成できます。

@Bean
@Description("Thymeleaf Template Resolver")
public ServletContextTemplateResolver templateResolver() {
    ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver();
    templateResolver.setPrefix("/WEB-INF/views/");
    templateResolver.setSuffix(".html");
    templateResolver.setTemplateMode("HTML5");

    return templateResolver;
}

@Bean
@Description("Thymeleaf Template Engine")
public SpringTemplateEngine templateEngine() {
    SpringTemplateEngine templateEngine = new SpringTemplateEngine();
    templateEngine.setTemplateResolver(templateResolver());
    templateEngine.setTemplateEngineMessageSource(messageSource());
    return templateEngine;
}


templateResolver

beanプロパティ

prefix



suffix

は、それぞれ

webapp

ディレクトリ内のビューページの場所とそのファイル名拡張子を示します。

Spring MVCの

ViewResolver

インタフェースは、コントローラから返されたビュー名を実際のビューオブジェクトにマッピングします。

ThymeleafViewResolver



ViewResolver

インターフェースを実装し、ビュー名が与えられたときにどのThymeleafビューをレンダリングするかを決定するために使用されます。

統合の最後のステップは、

ThymeleafViewResolver

をBeanとして追加することです。

@Bean
@Description("Thymeleaf View Resolver")
public ThymeleafViewResolver viewResolver() {
    ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
    viewResolver.setTemplateEngine(templateEngine());
    viewResolver.setOrder(1);
    return viewResolver;
}


3メッセージソースからの値の表示(プロパティファイル)


th:text =”#\ {key}”

tag属性を使用して、プロパティファイルの値を表示できます。これを機能させるには、プロパティファイルを

messageSource

beanとして設定する必要があります。

@Bean
@Description("Spring Message Resolver")
public ResourceBundleMessageSource messageSource() {
    ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
    messageSource.setBasename("messages");
    return messageSource;
}

これは、

welcome.message

キーに関連付けられた値を表示するためのThymeleaf HTMLコードです。

<span th:text="#{welcome.message}"/>


4モデル属性の表示


4.1. 単純属性


th:text =” $ \ {attributename}”

tag属性を使用して、モデル属性の値を表示できます。コントローラクラスに

serverTime

という名前のモデル属性を追加しましょう。

model.addAttribute("serverTime", dateFormat.format(new Date()));


serverTime

属性の値を表示するためのHTMLコード:

Current time is <span th:text="${serverTime}"/>


4.2. コレクション属性

model属性がオブジェクトのコレクションである場合、

th:each

タグ属性を使用してそれを繰り返すことができます。 2つのフィールド

id



name

を持つ

Student

モデルクラスを定義しましょう。

public class Student implements Serializable {
    private Integer id;
    private String name;
   //standard getters and setters
}

それでは、コントローラクラスのモデル属性として生徒のリストを追加します。

List<Student> students = new ArrayList<Student>();//logic to build student data
model.addAttribute("students", students);

最後に、Thymeleafテンプレートコードを使って生徒のリストを繰り返し処理し、すべてのフィールド値を表示することができます。

<tbody>
    <tr th:each="student: ${students}">
        <td th:text="${student.id}"/>
        <td th:text="${student.name}"/>
    </tr>
</tbody>


5条件付き評価


5.1.

if



unless



th:if =” $ \ {condition}”

属性は、条件が満たされた場合にビューのセクションを表示するために使用されます。

th:except =” $ \ {condition}”

属性は、条件が満たされない場合にビューのセクションを表示するために使用されます。


gender

フィールドを

Student

モデルに追加します。

public class Student implements Serializable {
    private Integer id;
    private String name;
    private Character gender;

   //standard getters and setters
}

このフィールドに、生徒の性別を示す2つの値(MまたはF)があるとします。単一の文字の代わりに「男性」または「女性」という単語を表示したい場合は、次のThymeleafコードを使用してこれを実現できます。

<td>
    <span th:if="${student.gender} == 'M'" th:text="Male"/>
    <span th:unless="${student.gender} == 'M'" th:text="Female"/>
</td>


5.2.

switch



case



th:switch

および

th:case

属性は、switchステートメント構造を使用して条件付きでコンテンツを表示するために使用されます。

前のコードは、

th:switch

および

th:case

属性を使用して書き直すことができます。

<td th:switch="${student.gender}">
    <span th:case="'M'" th:text="Male"/>
    <span th:case="'F'" th:text="Female"/>
</td>


6. ユーザー入力の処理

フォーム入力は、

th:action =” @ \ {url}”

および

th:object =” $ \ {object}”

属性を使用して処理できます。

th:action

はフォームアクションURLを提供するために使用され、

th:object

は送信されたフォームデータがバインドされるオブジェクトを指定するために使用されます。個々のフィールドは、

th:field =” ** \ {name}”

属性を使用してマッピングされます。ここで、

name

はオブジェクトの一致するプロパティです。


Student

クラスの場合は、入力フォームを作成できます。

<form action="#" th:action="@{/saveStudent}" th:object="${student}" method="post">
    <table border="1">
        <tr>
            <td><label th:text="#{msg.id}"/></td>
            <td><input type="number" th:field="** {id}"/></td>
        </tr>
        <tr>
            <td><label th:text="#{msg.name}"/></td>
            <td><input type="text" th:field="** {name}"/></td>
        </tr>
        <tr>
            <td><input type="submit" value="Submit"/></td>
        </tr>
    </table>
</form>

上記のコードで、

/saveStudent

はフォームアクションURL、

student

は送信されたフォームデータを保持するオブジェクトです。


StudentController

クラスはフォーム送信を処理します。

@Controller
public class StudentController {
    @RequestMapping(value = "/saveStudent", method = RequestMethod.POST)
    public String saveStudent(@ModelAttribute Student student, BindingResult errors, Model model) {
       //logic to process input data
    }
}

上記のコードで、

@ RequestMapping

アノテーションはフォームで提供されたURLでコントローラーメソッドをマッピングします。注釈付きメソッド

saveStudent()

は、送信されたフォームに必要な処理を実行します。


@ ModelAttribute

アノテーションはフォームフィールドを

student

オブジェクトにバインドします。


7. 検証エラーの表示


#fields.hasErrors()

関数は、フィールドに検証エラーがあるかどうかを確認するために使用できます。

#fields.errors()

関数は特定のフィールドのエラーを表示するために使用できます。フィールド名は、これら両方の機能の入力パラメータです。

フォーム内の各フィールドのエラーを繰り返し表示するためのHTMLコード。

<ul>
    <li th:each="err : ${#fields.errors('id')}" th:text="${err}"/>
    <li th:each="err : ${#fields.errors('name')}" th:text="${err}"/>
</ul>

上記の関数はフィールド名の代わりにワイルドカード文字

**

または定数

all

を受け入れてすべてのフィールドを示します。

th:each

属性は、各フィールドに存在する可能性がある複数のエラーを繰り返すために使用されます。

前のHTMLコードは、ワイルドカード

**

を使用して書き直されました。

<ul>
    <li th:each="err : ${#fields.errors('** ')}" th:text="${err}"/>
</ul>

あるいは定数

all

を使う:

<ul>
    <li th:each="err : ${#fields.errors('all')}" th:text="${err}"/>
</ul>

同様に、Springのグローバルエラーは

global

定数を使用して表示できます。

グローバルエラーを表示するためのHTMLコード:

<ul>
    <li th:each="err : ${#fields.errors('global')}" th:text="${err}"/>
</ul>


th:errors

属性はエラーメッセージを表示するためにも使用できます。

フォームにエラーを表示するための以前のコードは、

th:errors

属性を使って書き直すことができます。

<ul>
    <li th:errors="** {id}"/>
    <li th:errors="** {name}"/>
</ul>


8変換を使用する

二重括弧構文

\ {\ {}}

は、表示用にデータをフォーマット設定するために使用されます。

これはコンテキストファイルの

conversionService

beanのそのタイプのフィールド用に設定された

formatters

を利用します。


Student

クラスの名前フィールドはフォーマットされています。

<tr th:each="student: ${students}">
    <td th:text="${{student.name}}"/>
</tr>

上記のコードは、

WebMvcConfigurer

インターフェースから

addFormatters()

メソッドをオーバーライドすることによって構成された

NameFormatter

クラスを使用します。この目的のために、

@ Configuration

クラスは

WebMvcConfigurerAdapter

クラスをオーバーライドします。

@Configuration
public class WebMVCConfig extends WebMvcConfigurerAdapter {
   //...
    @Override
    @Description("Custom Conversion Service")
    public void addFormatters(FormatterRegistry registry) {
        registry.addFormatter(new NameFormatter());
    }
}


NameFormatter

クラスはSpringの

Formatter

インタフェースを実装します。


#conversions

ユーティリティは、表示用にオブジェクトを変換するためにも使用できます。効用関数の構文は

#conversions.convert(Object、Class)

です。ここで、

Object



Class

typeに変換されます。

小数部を削除して

student

object

percentage

フィールドを表示する

<tr th:each="student: ${students}">
    <td th:text="${#conversions.convert(student.percentage, 'Integer')}"/>
</tr>


9結論

このチュートリアルでは、ThymeleafをSpring MVCアプリケーションに統合して使用する方法を説明しました。

フィールドの表示方法、入力の受け入れ方法、検証エラーの表示方法、および表示用にデータを変換する方法の例も示しました。この記事に示されているコードの実用版はhttps://github.com/eugenp/tutorials/tree/master/spring-thymeleaf[a GitHub repository]にあります。