Thymeleafとは
Thymeleafというテンプレートエンジンがございます。
これはHTMLをそのまま使ってテンプレートにできるものでして、JSPはもとより、Velocoty、FreeMarkerよりもHTMLにやさしく記述できます。Spring frameworkともよく馴染みますし、非公式ながらStruts2でもプラグインが出ております。
Thymeleafで階層構造をもったオブジェクトを表示する方法
例えばUserクラスは、userid,usernameのプロパティをもっているとします。
@Data
public class User {
private String userid;
private String username;
}
@Data は project lombokのアノテーションです。
これを表示する入力フォームを考えた場合、要素は次のようになります。
<form action="subscribe.html" th:attr="action=@{/subscribe}" role="form" method="POST">
<div class="form-group">
<input type="text" id="userid" name="user.userid" value="ユーザーID" th:attr="value=${user.userid}" />
<input type="text" id="username" name="user.username" value="ユーザー名" th:attr="value=${user.username}" />
</div>
</form>
このように、ピリオドつなぎでプロパティを指定すると、オブジェクト階層を構成して値の表示をします。ThymeleafはOGNLを使っており、java.util.Mapでもjava.util.Listでも、String配列もカンタンに扱えます。
オブジェクトがnullだった場合は?
例えば先ほどのUserクラス、nullを渡した場合はどうなるか。何とランタイム例外で落ちます。
これについては次の2通りの対応があります。
- OGNLのNullHandlerを実装する
- Thymeleafのタグ階層でnull時の制御をする
ここでは後者を使った場合を紹介します。
Thymeleafを使ったオブジェクト階層と、子要素の関連
オブジェクト階層の記述方法には、4.3. expressions-on-selections-asterisk-syntaxにもあるように、${...}で記載したオブジェクトの子要素を*{...}で表記できます。
ポイントは、親となるオブジェクトをHTMLタグの要素の階層にあわせて記述することです。
先ほどのHTMLテンプレートを書きかえると、次のようになります。
<form action="subscribe.html" th:attr="action=@{/subscribe}" role="form" method="POST">
<div class="form-group" th:object="${user}">
<input type="text" id="userid" name="user.userid" value="ユーザーID" th:attr="value=*{userid}" />
<input type="text" id="username" name="user.username" value="ユーザー名" th:attr="value=*{username}" />
</div>
</form>
しかしこの状態でも ${user}はnullのままなので、後続の*{userid}で再びランタイム例外となります。
そこで、HTML上でnullチェックを実施して、回避する方法が以下の例です。
<form action="subscribe.html" th:attr="action=@{/subscribe}" role="form" method="POST">
<div class="form-group" th:object="${#objects.nullSafe(user, new sample.vo.User())}">
<input type="text" id="userid" name="user.userid" value="ユーザーID" th:attr="value=*{userid}" />
<input type="text" id="username" name="user.username" value="ユーザー名" th:attr="value=*{username}" />
</div>
</form>
OGNLで記述できますので、HTML中で、new しております。