Spring Boot アプリ で Thymeleaf に Java のオブジェクトを渡す Model#addAttribute の使い方
Java から Thymeleaf に値を渡すには、Model#addAttribute メソッドを使います。
目次
${taskForm.id}: Thymeleaf で Java の変数を参照する方法
Thymeleaf で Java の変数を参照する方法は、${taskForm.id} という記法を使います。
taskForm は、Java のコードから Thymeleaf に渡した変数につけられたキー名です。
もし、Java から taskForm というキー名のオブジェクトが渡されていない場合、id フィールドを参照するタイミングで次のようなエラーが発生します:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
...
There was an unexpected error (type=Internal Server Error, status=500).
An error happened during template parsing (template: "URL [...]")
org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "URL [...]")
...
Caused by: org.attoparser.ParseException: Exception evaluating SpringEL expression: "taskForm.id" (template: ...)
...
Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "taskForm.id" (template: "issues/creationForm" - line 8, col 4)
...
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1007E: Property or field 'id' cannot be found on null
基本:Model#addAttribute("key", value)
Java から Thymeleaf に値を渡す方法は、Model#addAttribute メソッドを使います。
次にように書くと、Thymeleaf のテンプレートで form という変数に TaskForm クラスのインスタンスが渡されます。
@Controller
@RequestMapping("/tasks")
public class FormController {
@GetMapping
public String index(Model model) {
model.addAttribute("form", new TaskForm());
return "index";
}
}
このとき、Thymeleaf のテンプレートでは次のように form 変数を参照できます。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Thymeleaf Example</title>
</head>
<body>
<p th:text="${form.taskId}"></p>
</body>
</html>
応用:Model#addAttribute(value) で key を省略する
Model#addAttribute メソッドの第一引数に key を指定しない場合、 value のクラス名の先頭を小文字にしたもの が key として使われます。
引用元:Conventions (Spring Framework 6.1.8 API):
Determine the conventional variable name for the supplied Object based on its concrete type. The convention used is to return the un-capitalized short name of the Class, according to JavaBeans property naming rules.
For example:
- com.myapp.Product becomes “product”
- com.myapp.MyProduct becomes “myProduct”
- com.myapp.UKProduct becomes “UKProduct”
For arrays the pluralized version of the array component type is used. For Collections an attempt is made to ‘peek ahead’ to determine the component type and return its pluralized version.
日本語訳:
提供されたオブジェクトの具体的な型に基づいて、慣習的な変数名を決定します。使用される慣習は、JavaBeansプロパティ命名規則に従い、クラスの短縮名を小文字に変換して返すことです。
例:
- com.myapp.Product は product
- com.myapp.MyProduct は myProduct
- com.myapp.UKProduct は UKProduct
配列の場合は、配列の要素型を複数形にした名前が使用されます。コレクションの場合は、要素型を先読みしてその複数形を返すように試みます。
例えば、以下の例のように、model.addAttribute(new TaskForm()) として場合を考えます。
@Controller
@RequestMapping("/tasks")
public class FormController {
@GetMapping
public String index(Model model) {
model.addAttribute(new TaskForm());
return "index";
}
}
このとき、Thymeleaf のテンプレートでは次のように taskForm 変数を参照できます。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Thymeleaf Example</title>
</head>
<body>
<p th:text="${taskForm.taskId}"></p>
</body>
</html>
詳細をまとめると、次のようになります:
Model#addAttribute(new TaskForm())より、addAttributeに渡す引数のクラス名がTaskFormであるTaskFormクラスの先頭を小文字にしたものが key として使われる- つまり、
taskFormという key が使われる
まとめ
- Java のコードから Thymeleaf に値を渡すときは、
Model#addAttributeメソッドを使う Model#addAttribute("form", new TaskForm())と書くと、Thymeleaf では “${form} で参照できるModel#addAttribute(new TaskForm())と書くと、Thymeleaf では “${taskForm} で参照できる