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} で参照できる