【Spring Boot入門】#1 Spring Boot + Thymeleafで新規登録画面を作成する

## はじめに
自身の知識のアウトプットも兼ねて、新人研修用に作成した記事となります。Spring Bootを学び始めた方を対象とした内容になっています。

開発環境や依存関係については、前回の記事を参照ください。

https://qiita.com/ioaio/items/10af72b06252541ca1a7

## 概要
企業情報登録画面を作成します。
クライアントからのリクエスト(URL)を元に画面を表示する為のControllerの作成と、遷移先である画面をThymeleafで作成していきます。

#### 完成イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3917178/a4da3148-81be-3bd1-f667-14b2b29fde1e.png)

## パッケージ構成
赤枠で囲ったパッケージ、クラス、HTMLファイルを今回作成していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3917178/fe84d9ed-03cb-b751-65ae-0acbc68d19ae.png)

## Formクラスの作成
登録画面の項目をViewとController間で受け渡すためのFormオブジェクトを作成します。
`配置先：src > main > java > com > example > demo > controller > form > CompanyForm.java`

```Java:CompanyForm.java
package com.example.demo.controller.form;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class CompanyForm {

	private String companyName;	// 会社名
	
	private String employees;	// 従業員数
	
	private String est;	// 設立日
}
```

#### @￰Data
getter、setter、toStringなどの基本的メソッドを自動定義します。

#### @￰AllArgsConstructor
全ての項目を引数として持つコンストラクタを自動定義します。

#### @￰NoArgsConstructor
引数なしのコンストラクタを自動定義します。

## Controllerの作成
CompanyController.javaを作成します。
`配置先：src > main > java > com > example > demo > controller > CompanyController.java`

```java:CompanyController.java
package com.example.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import com.example.demo.controller.form.CompanyForm;

@Controller
public class CompanyController {

	// 登録フォームの表示
	@GetMapping("company/register")
	public String showForm(Model model) {
		model.addAttribute("companyForm", new CompanyForm());
		return "register";
	}

}
```

#### @￰Controller
クラスがコントローラーとして認識されます。

#### @￰GetMapping(path)
GETリクエストのみをマッピングします。
@￰GetMappingでリクエストがGetメソッドであること、`"/company/register"`でドメイン以下のURLが/company/registerであることを定義しています。

#### Modelオブジェクト
引数のModelオブジェクトはControllerからViewへと値を渡すために利用できます。

#### model.addAttribute("key", value);
第一引数に識別子、第二引数にViewへ渡したいオブジェクトや値を指定します。
今回の場合、空のFormオブジェクト`CompanyForm`を生成し、それをViewへ`companyForm`という属性名で渡しています。

#### retuen "文字列";
showFormメソッド自体は"register"という文字列を返却しています。
この"register"という文字列はテンプレートファイル名の指定であり、Viewがtemplatesフォルダ内のテンプレートファイル「文字列.html」(register.html)を探し出し、クライアントに返却します。

## Viewの作成（Thymeleaf）
register.htmlを作成します。
`配置先：src > main > resources > templates > register.html`

```HTML:register.html
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>新規登録画面</title>
</head>
<body>
	<h1>企業情報登録フォーム</h1>
	<form th:action="@{/company/register}" th:object="${companyForm}" method="post">
		<table>
			<tr>
				<td><label for="company">会社名：</label></td>
				<td><input type="text" th:field="*{companyName}" /></td>
			</tr>
			<tr>
				<td><label for="emp">従業員数：</label></td>
				<td><input tyape="text" th:field="*{employees}" /></td>
			</tr>
			<tr>
				<td><label>設立日：</label></td>
				<td><input type="date" th:field="*{est}" /></td>
			</tr>
			<tr>
				<td><input type="submit" value="登録する" /></td>
			</tr>
		</table>
	</form>
</body>
</html>
```

#### xmlns:th="http://www.thymeleaf.org"
HTMLタグにxmlns(xml名前空間）宣言を追加し、名前空間("th")を定義しています。Tymeleafを使う際は必須のおまじないです。

#### th:属性名="Tymeleaf式"
こう書くことでTymeleafが動的に式を書き換えてくれます。

#### th:action="@{path}"
`th:action`には、リンクURL式`@{}`を用います。
ここではフォームの送信先(POST)に"/register"を指定しています。

#### th:object="${フォームオブジェクト}"
フォーム内で参照するオブジェクトを指定しています。
※ViewはControllerから空のFormオブジェクト`CompanyForm`を`companyForm`という属性名で受け取っています。

#### th:object="${フォームオブジェクト}" ＋ th:field=*{属性名}
フォームで入力を受け取る際に、セットで使用します。
`th:object`にフォームオブジェクトを、`th:field`に対応するフィールドを書くことで、フォームに入力された値を受け取ることができます。これをフォームバインディングと言います。

`*{companyName}`はフォーム内で参照しているオブジェクト`companyForm`の`companyName`プロパティを参照するという意味で、変数式を利用し`"${companyForm.companyName}"`と実装した場合と同様の結果になります。

また、th:field属性名をinput要素に適用すると、id属性、name属性、value属性が指定した値で勝手に付加されます。

## 動作確認
ブラウザのアドレスバーから`http://localhost:8080/company/register`にアクセスしてみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3917178/8c623aca-d163-acca-b5d0-a090e77f60fb.png)

作成した企業情報登録フォーム（register.html）が表示されるました！

## 参考サイト
https://cs27.org/wiki/kobespiral2021/?SpringBoot/Thymeleaf

https://terasolunaorg.github.io/guideline/current/ja/ArchitectureInDetail/WebApplicationDetail/Thymeleaf.html