概要
thymeleafでよく使った構文をまとめます。
後でデバッグして確認したいのでgithubにまとめます。
開発環境
OS:Windows10
IDE:IntelliJ comunnity
Javaバージョン:11(pom.xmlでバージョン変えればok、17は確認済み)
Spring bootバージョン:2.7.0
thymeleafバージョン:3.0.15.RELEASE
フォルダ構成
赤丸で囲まれた部分を見ます
実行方法
1.githubからプロジェクトをクローンします。branchは「thymeleaf」を選択します。
https://github.com/RYA234/spring_boot_memo
2.src/main/java/com/example/spring_boot_memo/SpringBootMemoApplicationを実行します。
3.以下URLを開きます
http://localhost:5000/
開くと以下画面が表示されます。
内容
1 コントローラーからhtml側に変数を渡す。
Controller側の処理
int型の変数Countを宣言します。値は1234とします。
model.addAttribute()でview側にCountの値を渡します。
OKとNGとも同じ処理をしています。
view側の処理
Controllerで渡された変数を表示します。
OKとNGで変数部分が違うのでエラーになります。
OKな場合
Controller
@RequestMapping(value = "thymeleaf/1_menu", params = "OK", method = RequestMethod.POST)
public String thymeleaf_1_menuOkController(Model model)
{
int Count = 1234;
model.addAttribute("CountName",Count);
return "thymeleaf/1_menu_ok";
}
html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"></meta>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>1.コントローラーから関数に渡す_OK</title>
</head>
<body>
コントロールからの値の取得に成功しました。
CountNameの値は<div th:text="${CountName}"></div>
</body>
</html>
NGな場合
Controller
@RequestMapping(value = "thymeleaf/1_menu", params = "NG", method = RequestMethod.POST)
public String thymeleaf_1_menuNgController(Model model)
{
int Count = 1234;
model.addAttribute("CountName",Count);
return "thymeleaf/1_menu_ng";
}
html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"></meta>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>1.コントローラーから関数に渡す_NG</title>
</head>
<body>
このページは表示されず Whitelabel Error Pageが表示されます。
CountNameの値は<div th:text="{CountName}"></div>
<!--th:text="{CountName}"だとNGになる -->
</body>
</html>
エラー箇所の発見方法
ブラウザ上で「line」を検索するとエラー箇所を特定できます。
今回の事例に当てはめますと「Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Could not parse as expression: "{CountName}" (template: "thymeleaf/1_menu_ng" - line 10, col 18)」
1_menu_ng.htmlの10行目にエラーがあると確認できます。
2 コントローラーからhtml側にクラスを渡す場合
変数を渡すときとは表記の仕方が若干かわります。
変数とクラスの渡し方を把握しとかないとごっちゃになり汚いソースコードになります。(経験談)
OKな場合
Controller
@RequestMapping(value = "thymeleaf/2_menu", params = "OK", method = RequestMethod.POST)
public String thymeleaf_2_menuOkController(Model model)
{
ModelForm modelForm = new ModelForm();
modelForm.setCount(123);
modelForm.setName("NAMAE");
model.addAttribute(modelForm);
return "thymeleaf/2_menu_ok";
}
html
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"></meta>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>2.コントローラーからhtml側にクラスを渡す_OK</title>
</head>
<body>
コントロールからの値の取得に成功しました
<div th:object ="${modelForm}">
countは<div th:text="*{count}" th:name="*{count}"></div>
です。
</bn></br>
nameは<div th:text="*{name}" th:name="*{name}"></div>
です。
</div>
</body>
</html>
NGな場合
Controller
@RequestMapping(value = "thymeleaf/2_menu", params = "NG", method = RequestMethod.POST)
public String thymeleaf_2_menuNgController(Model model)
{
ModelForm modelForm = new ModelForm();
modelForm.setCount(123);
modelForm.setName("NAMAE");
model.addAttribute(modelForm);
return "thymeleaf/2_menu_ng";
}
html
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"></meta>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>2.コントローラーからhtml側にクラスを渡す_NG</title>
</head>
<body>
このページは表示されず Whitelabel Error Pageが表示されます。
<div th:object ="${ModelForm}">
countは<div th:text="${count}" th:name="${count}"></div>
です。
</bn></br>
nameは<div th:text="${name}" th:name="${name}"></div>
です。
</div>
</body>
</html>
表示結果
Chrome検証機能から値が入っていないことを確認
エラー箇所の発見方法
Chromeの検証機能で確認します。
3 html側からコントローラーに変数を渡す場合
OKな場合
Controller
@RequestMapping(value = "thymeleaf/3_menu", params = "OK", method = RequestMethod.POST)
public String thymeleaf_3_menuOkController(Model model,ModelForm modelForm)
{
System.out.print("3_okのmodelFormについて");
System.out.print(modelForm);
return "thymeleaf/3_menu_ok";
}
html
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"></meta>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>3.コントローラーからhtml側にクラスを渡す_OK</title>
</head>
<body>
コントロールからの値の取得に成功しました
<div th:object ="${modelForm}">
countは<div th:text="*{count}" th:name="*{count}"></div>
nameは<div th:text="*{name}" th:name="*{name}"></div>
です。
</bn></br>
です。
</div>
</body>
</html>
NGな場合
Controller
@RequestMapping(value = "thymeleaf/3_menu", params = "NG", method = RequestMethod.POST)
public String thymeleaf_3_menuNgController(Model model,ModelForm modelForm)
{
System.out.print("3_ngのmodelFormについて");
System.out.print(modelForm);
return "thymeleaf/3_menu_ng";
}
html
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"></meta>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>3.コントローラーからhtml側にクラスを渡す_NG</title>
</head>
<body>
コントロールからの値の取得に失敗しました
<div th:object ="${modelForm}">
countは<div th:text="${count}" th:name="${count}"></div>
nameは<div th:text="${name}" th:name="${name}"></div>
です。
</br>
です。
</div>
</body>
</html>
エラー箇所の発見方法
Chromeの検証機能で確認します。
4 繰り返しをする場合
OKな場合
Controller
@RequestMapping(value = "thymeleaf/4_menu", params = "OK", method = RequestMethod.POST)
public String thymeleaf_4_menuOkController(Model model)
{
List<ModelForm> list = new ArrayList<ModelForm>();
ModelForm modelForm = new ModelForm();
modelForm.setCount(1);
modelForm.setName("aaaaa");
list.add(modelForm);
modelForm.setCount(2);
modelForm.setName("ABABAAA");
list.add(modelForm);
modelForm.setCount(3);
modelForm.setName("CACAAA");
list.add(modelForm);
model.addAttribute("list",list);
System.out.print("4_okのlist_OKについて");
System.out.print(list);
return "thymeleaf/4_menu_ok";
}
html
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"></meta>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>4.繰り返しについて_OK</title>
</head>
<body>
コントロールからの値の取得に成功しました
<table>
<thead>
<tr>
<th>count </th>
<th>名前 </th>
</tr>
</thead>
<tbody>
<tr th:each="item : ${list}">
<td th:text ="${item.count}"></td>
<td th:text ="${item.name}"></td>
</tr>>
</tbody>>
</table>
nameは<div th:text="${list}" th:name="${list}"></div>
</body>
</html>
NGな場合
model.addAttribute();の使い方について詰まりましたね
Controller
@RequestMapping(value = "thymeleaf/4_menu", params = "NG", method = RequestMethod.POST)
public String thymeleaf_4_menuNgController(Model model)
{
List<ModelForm> list = new ArrayList<>();
ModelForm modelForm = new ModelForm();
modelForm.setCount(1);
modelForm.setName("aaaaa");
list.add(modelForm);
modelForm.setCount(2);
modelForm.setName("ABABAAA");
list.add(modelForm);
modelForm.setCount(3);
modelForm.setName("CACAAA");
list.add(modelForm);
model.addAttribute(list);
System.out.print("4_okのlist_NGについて");
System.out.print(list);
return "thymeleaf/4_menu_ng";
}
html
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"></meta>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>4.繰り返しについて_NG</title>
</head>
<body>
コントロールからの値の取得に失敗しました。
<table>
<thead>
<tr>
<th>count </th>
<th>名前 </th>
</tr>
</thead>
<tbody>
<tr th:each="item : ${list}">
<td th:text ="{item.count}"></td>
<td th:text ="{item.name}"></td>
</tr>>
</tbody>>
</table>
</body>
</html>
表示結果
Chromeの検証結果はスカスカになっていますね。
IDE側のデバッグじゃ確認できないのが手痛かったですね…
(Chromeの検証を使う習慣がなかった…)
まとめ
IntelliJのデバッグ機能とChromeの検証機能両方使うと問題の突き止めが早いと分かりました。
私の場合は
1.IntelliJのデバッグモードでControllerを通っているか、値が入っているか確認
2.Chromeの検証機能で確認するようになりました。
参考資料
thymeleaf 公式ドキュメント
https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf_ja.html
後悔しないためのSpring Boot 入門書:私が初めてthymeleaf触ったときに参考にした本です。