今回は、Javaのテンプレートエンジン「Thymeleaf(タイムリーフ)」で、プロパティの戻り値としてリスト(List
)が返ってきたとき、それが「入れ子構造」になっている場合のアクセス方法について、新人エンジニアの方向けに丁寧に解説していきます。
「入れ子のリストって?」「どうやってHTML上で表示するの?」といった疑問に答えていきますので、安心して読み進めてください!
Thymeleafとは?
まずは簡単におさらいです。
Thymeleafは、Javaと一緒に使われるテンプレートエンジンで、HTMLにJavaのオブジェクトの値を埋め込むことができます。Spring Bootと一緒によく使われており、@Controller
で返したデータを、HTMLに動的に反映させるのに便利です。
入れ子のリストとは?
例で見てみよう!
たとえば、以下のようなJavaのモデルクラスがあったとします。
public class Company {
private List<Department> departments;
// ゲッター・セッター省略
}
public class Department {
private List<Employee> employees;
// ゲッター・セッター省略
}
public class Employee {
private String name;
}
このように、Company → Department → Employee と3段階でリストがネスト(入れ子)になっています。
Thymeleafでのアクセス方法
th:eachでループ処理
Thymeleafでは、th:each
属性を使ってリストをループで展開します。
入れ子の場合も同じように、ネストしてループさせることができます。
実際のコード例
以下は、入れ子のリストにアクセスしてHTMLで表示する例です。
<div th:each="department : ${company.departments}">
<h2 th:text="${department.name}">部署名</h2>
<ul>
<li th:each="employee : ${department.employees}"
th:text="${employee.name}">従業員名</li>
</ul>
</div>
解説
${company.departments}
→Company
オブジェクトのdepartments
プロパティ(リスト)にアクセス。th:each="department : ..."
→ ループ変数department
を定義して、1つ1つのDepartment
を処理。- その中で再度
department.employees
をループし、employee.name
を表示しています。
例え話で理解しよう!
イメージとしては「学校(Company)に複数のクラス(Department)があり、それぞれのクラスに生徒(Employee)がいる」感じです。
HTMLでは、
- 学校を表示し
- クラスごとに区切り
- それぞれのクラスに属する生徒をリスト表示している
と考えると分かりやすいですね!
よくあるつまずきポイント
nullを参照してエラーになる
department.employees
がnullだと、ループでNullPointerException
的なエラーになります。Thymeleafはある程度nullに強いですが、安全策として次のように書くと良いでしょう。
<li th:each="employee : ${department.employees != null ? department.employees : {}}"
th:text="${employee.name}">従業員名</li>
これはJavaの三項演算子を使って「nullなら空のリスト」を渡している例です。
表にまとめてみよう
階層 | オブジェクト名 | アクセス方法 |
---|---|---|
1階層目 | company | ${company} |
2階層目 | departments | ${company.departments} |
3階層目 | employees | ${department.employees} |
メリット・デメリット
メリット
- Javaのデータ構造そのまま使えるため、学習コストが低い
- 可読性が高い(HTMLの構造と一致する)
デメリット
- 入れ子が深くなると、可読性が下がる
- null処理を丁寧にしないとエラーになりやすい
今後の学習の指針
ここまで理解できたら、次は以下の内容を勉強してみましょう!
th:if
やth:unless
を使った条件分岐- リスト内でインデックス番号を表示する方法(
Stat.index
)
さらに実践的なテンプレートが書けるようになりますよ!
ご不明点や具体的なソースコードをもとにした質問があれば、いつでも聞いてくださいね。