春にThymeleafを使用することへの紹介
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]にあります。