Spring-Boot でControllerからThymleafへ、Formクラスを受け渡す

# 目的
Thymeleafで表示されているテンプレートへ、Controllerから、オブジェクトを受け渡す時の最小構成

# 前提
- Thymleafの導入は済んでいること
- Spring-Boot 1.5.1.RELEASE

# 手順
## Formクラスですること
- Formクラスと言っているのは、ripositoryではなく、普通のjavaクラスに値を乗せてコントローラ、ビュー間でやり取りをする時受け渡すオブジェクトのクラス

- javaクラスは、POJOなクラスでいい
- GetterとSetterが必ず必要
- Lanbokが使える。 @Dataをつけるだけでアクセッサはオーケー

```java:ContractListForm.java
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メソッドで、最初の引数で画面側でのインスタンス名を定義します、画面からはこの名前で受け取ります
第２引数で実際に渡すオブジェクトを渡します

```java:ContractListsController
    @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タグでオブジェクトを受け取ります

```html:index.html
<form method="post" action="/Contract/search" th:object="${contractListF}">
```
-  th:object="${contractListF}"
-  th:objectタグで$に続いてaddObjectで指定した名前を受け取ります、ここにインスタンスが入ってくる

```html:index.html
<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のオブジェクトを受け取るときは、以下のような書き方をします

```html:index.html
<tr th:each="obj : ${contractList}">
				<td th:text="${obj.anken_kbn}"></td>
				<td th:text="${obj.anken_mei}"></td>
```

ここへ送っているコントローラのリクエストメソッドは、実はさっきのと同じで、本当はこうなっていました

```java:ContractListsController.java
@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}"|