目的
Thymeleafで表示されているテンプレートへ、Controllerから、オブジェクトを受け渡す時の最小構成
前提
- Thymleafの導入は済んでいること
- Spring-Boot 1.5.1.RELEASE
手順
Formクラスですること
-
Formクラスと言っているのは、ripositoryではなく、普通のjavaクラスに値を乗せてコントローラ、ビュー間でやり取りをする時受け渡すオブジェクトのクラス
-
javaクラスは、POJOなクラスでいい
-
GetterとSetterが必ず必要
-
Lanbokが使える。 @Dataをつけるだけでアクセッサはオーケー
package com.contract.web;
import lombok.Data;
@Data
public class ContractListForm{
private String anken_kbn; // 案件区分
private String anken_name; // 案件名
}
Controllerですること
-
Formクラスのインスタンスを生成し、コントローラでもつ
-
画面へFormクラスのインスタンスを渡す
-
先ほどのクラスを、@ModelAttributeアノテーションのついたメソッドで生成
このアノテーション付きのメソッドは、@RequestMapping付きのメソッドが呼ばれた時(リクエストを受けた時)に自動的に呼び出されます
このアノテーションのついたメソッドで、フォームクラスのインスタンスを生成します
ここで作成されたインスタンスはリクエストスコープに登録されます -
@RequestMappingメソッドで、画面へオブジェクトを渡します。
addObjectメソッドで、最初の引数で画面側でのインスタンス名を定義します、画面からはこの名前で受け取ります
第2引数で実際に渡すオブジェクトを渡します
@ModelAttribute
ContractListForm setUpForm() {
return new ContractListForm();
}
@RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView index(ModelAndView mav) {
mav.setViewName("index");
mav.addObject("contractListF", new ContractListForm()); // 検索フォーム用インスタンス
return mav;
}
テンプレートファイルですること
- まずformタグでオブジェクトを受け取ります
<form method="post" action="/Contract/search" th:object="${contractListF}">
- th:object="${contractListF}"
- th:objectタグで$に続いてaddObjectで指定した名前を受け取ります、ここにインスタンスが入ってくる
<input type="text" th:field="*{anken_kbn}" class="form-control" aria-describedby="basic-addon2"></input>
<input type="text" th:field="*{anken_name}" class="form-control" aria-describedby="basic-addon2"></input>
- その中のフィールドは
- th:field="*{anken_name}"
- th:fieldタグで受け取り、こちらは*{ アスタリスクのカッコでうけとる。フィールド名をそのままかく
このへんの設定ができていないと、以下のようなエラーが発生します
- アクセッサの不備を出していますが、実際には上のルールができていない時にも同じエラーメッセージが出ます。
org.springframework.beans.NotReadablePropertyException: Invalid property 'contractListForm' of bean class [com.contract.web.ContractListForm]: Bean property 'contractListForm' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
混乱したポイント
- 自分が混同したのは、repositoryのオブジェクトを受け取るときは、以下のような書き方をします
<tr th:each="obj : ${contractList}">
<td th:text="${obj.anken_kbn}"></td>
<td th:text="${obj.anken_mei}"></td>
ここへ送っているコントローラのリクエストメソッドは、実はさっきのと同じで、本当はこうなっていました
@RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView index(ModelAndView mav) {
mav.setViewName("index");
Iterable<TMitsumoriHdrEntity> hdrEntityList = hdrDao.findAll();
mav.addObject("contractList", hdrEntityList);
mav.addObject("contractListF", new ContractListForm()); // 検索フォーム用インスタンス
return mav;
}
- ここで、daoから取得したEntityのリストをcontractListという名前で以下のように渡しています。
mav.addObject("contractList", hdrEntityList);
- この場合、リストでEntityが受け取られていて、それをループで取得します、その場合は
<tr th:each="obj : ${contractList}">
- th:eachで受け取って、変数 : ${でインスタンス名}
- その変数に対して
<td th:text="${obj.anken_kbn}"></td>
- 値を表示する th:text に 変数名.フィールド名
- という書き方をします
まとめると
インスタンス | インスタンスの取り方 | フィールドの取り方 |
---|---|---|
Form(POJO)のオブジェクト | th:object="${contractListF}" | th:field="*{anken_kbn} |
Entityのオブジェクト | th:each="obj : ${contractList}" | th:text="${obj.anken_kbn}" |