Spring Boot + Spring MVC ～サンプルアプリ実装～

# Spring MVCについて
Spring MVCは、Webアプリケーションを作成するためのフレームワークです。
MVCはソフトウェア設計の１つで、機能を「Model(モデル)」「View(ビュー)」「Controller(コントローラ)」の３つに分割して、それらが連携して処理をします。通常、MVCは以下のような図で構成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244937/32ef1362-a7c1-185c-b7e9-3ca8f7cfbf49.png)

Spring MVCでは、MVCの中でも「Front Controller(フロントコントローラ)パターン」に分類されています。これは、中央のフロントコントローラが処理の中継を行い、管理するパターンです。図にすると以下のような構成になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244937/6afd50d2-096a-7067-4820-5050cbc3872d.png)

フロントコントローラは、Spring MVCが管理するコントローラです。開発する上では、その処理内容を意識する必要がありません。メインとして意識する必要があるのは、基本的なModel-View-Controllerの部分です。

- Model・・・モデルは、アプリケーションの動的なデータ構造です。Springでは、ごく普通のJavaオブジェクト（POJO:Plain Old Java Object）やEntityなどが、これに該当します。
- View(template)・・・ビューは、図や表などの画面情報を表現します。SpringではThymeleaf(タイムリーフ)を使ったHTMLテンプレートファイルが、これに該当します。
- Controller・・・コントローラは、入力を受け入れて処理を行います。Springでは@Controllerアノテーションを付けたクラスが、これに該当します。

Spring MVCを利用する場合、Servletを意識する事はありませんが、Spring MVCも内部ではServletを使用してリクエストに対する処理を行っています。

# 開発環境
サンプルアプリケーションの作成は、下記環境に[Spring Tool Suite(STS)の導入](https://qiita.com/t-shin0hara/items/d60116ab299a4dc8a9d0)が完了している事を前提とします。

| 種別               | プロダクト                  |
|:-------------------|:---------------------------|
| JVM                | Java 11                    |
| OS                 | Windows 10 64bit           |

# サンプルアプリケーションの作成
Spring Bootを利用して実際に簡単なアプリケーションを作成します。作成するのは、以下の画面のようにテキストフィールドに氏名・メールアドレス・年齢を入力して[送信]ボタンを押下すると、入力した情報を表示する画面へ遷移する、いわゆるエコーアプリケーションです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244937/079acb19-fd64-ab7e-e60f-97d706333c6d.png)

アプリ作成完了時のフォルダ構成は下記となります。
![structure.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244937/4d5bb162-95a5-1530-4d97-5302b1bc0ac7.png)

# 1. 新規プロジェクト作成
Spring Tool Suite(STS)のメニューから、[ファイル] -> [新規] -> [Spring スターター・プロジェクト] を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244937/38d50e02-171e-71d1-ca01-37e75e15b271.png)

[新規 Spring スターター・プロジェクト]ダイアログで、以下を入力して[次へ]ボタンを押下します。
- 名前：spring-mvc1
- Java バージョン：11
![dialog.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244937/2735a33f-cc44-9866-0af2-607f3f523008.png)

依存関係で以下にチェックを入れて[完了]ボタンを押下します。
▼開発ツール
　・**Spring Boot DevTools**
　・**Lombok**
▼テンプレート・エンジン
　・**Thymeleaf**
▼Web
　・**Spring Web**
![dialog.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244937/38b649f5-9584-76ff-c68c-7b13fb1cf68d.png)

```text:参考情報
【依存関係で指定したモジュールについて】
　Spring Boot DevTools・・・Spring Bootの開発ツールです。Javaコード、HTMLファイル、プロパティファイルなどの修正を検知して実行中のアプリに即時反映（ホットデプロイ）してくれるなど、開発に便利なツールが含まれています。
　Thymeleaf（タイムリーフ）・・・Spring Bootで標準的に使われるHTMLのテンプレートエンジンです。※Spring BootではJSPの使用は非推奨となっています。
　Spring Web・・・Spring MVCを使ったWebアプリケーションが作成可能となります。
　Lombok（ロンボック）・・・定型コード記述の省力化に役立つJavaアノテーションライブラリです。
```
```text:参考情報
【作成したプロジェクト内のファイルについて（下記イメージ参照）】
　SpringMvc1Application.java・・・mainメソッドが宣言されているクラスです。SpringBootの起動はこのクラスから行います。@SpringBootApplicationアノテーションが定義されています。
　application.properties・・・Spring Bootのプロパティファイルです。
　pom.xml・・・Mavenの設定ファイルです。Mavenは、Javaプログラムをビルドするためのツールです。様々な機能がありますが、特に便利な機能は、アプリケーションが利用するライブラリの自動取得です。
```
![structure.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244937/081fe2fb-a43c-2c6b-d71d-cbf5d182ff80.png)

# 2. Lombokの導入設定
Springスターター・プロジェクト作成時に依存関係で**Lombok**を指定しただけでは、作成するアプリケーション実行時に**Lombok**が正常動作しない為、以下のとおりプロジェクトフォルダ直下の**「pom.xml」**を修正してください。

```xml:pom.xml（変更前）
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
```
```xml:pom.xml（変更後）
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.18.12</version>
			<scope>provided</scope>
		</dependency>
```

# 3. モデルの作成
[com.example.demo]で右クリック -> [新規] -> [クラス] を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244937/1bb8cfa9-0f63-e4f3-7a49-afce85b95d2f.png)
[新規Javaクラス]ダイアログで、以下を入力して[完了]ボタンを押下します。
- パッケージ：**com.example.demo.model**（modelを追加）
- 名前：**User**
![dialog.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244937/7af92e2f-7f12-08cc-be02-46a15a2eb782.png)

User.javaを以下のとおり編集します。

```java:User.java
package com.example.demo.model;

import lombok.Data;

@Data
public class User {
    private String name;
    private String email;
    private Integer age;
}
```
```text:参考情報
　@Data・・・Lombokの@Dataアノテーションです。GetterやSetter、toStringなどのコードを自動生成してくれます。自動生成されている事は、[アウトライン]ビューで確認できます（下記イメージ参照）。
```
モデルには、GetterやSetterが必要ですが、この定型コードを補ってくれるのがLombokです。
下のイメージのとおり、Userクラスにはフィールド定義のみしかしていませが、アウトラインにはGetterやSetterが表示されている事が分かります。
当然ですが、Lombokを使用しない場合は、GetterやSetterの記述が必要となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244937/e9c2e675-e031-3ee1-5a46-79bc47809727.png)

# 4. コントローラの作成
[com.example.demo]で右クリック -> [新規] -> [クラス] を選択する。
[新規Javaクラス]ダイアログで、以下を入力して[完了]ボタンを押下します。
- パッケージ：**com.example.demo.controller**（controllerを追加）
- 名前：**HomeController**

HomeController.javaを以下のとおり編集します。

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

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import com.example.demo.model.User;

@Controller
public class HomeController {

    @GetMapping("/form")
    private String readForm(@ModelAttribute User user) {
        return "form";
    }
    
    @PostMapping("/form")
    private String confirm(@ModelAttribute User user) {
        return "confirm";
    }
}
```
```text:参考情報
　@Controller・・・このクラスをコントローラとして機能させる場合に指定します。
　@GetMapping・・・アノテーション付与によりHTTPのGETリクエストを受け付けます。ここでは"http://localhost:8080/form"のGETリクエストを受け付けます。
　@PostMapping・・・アノテーション付与によりHTTPのPOSTリクエストを受け付けます。ここでは"http://localhost:8080/form"のPOSTリクエストを受け付けます。
　@ModelAttribute・・・モデル属性にバインドします。バインドとは、日本語で「結び付ける」「関連付ける」などの意味です。ここでは、入力画面の「氏名」が<input type="text" name="name">の場合、リクエストを受け付けたタイミングでSpringが自動でUserクラスのnameプロパティに画面入力値を設定してくれます。これは、データバインディングと呼ばれ、パラメータ取得コードの記述が不要となります。
```

# 5. Thymeleafテンプレートの作成
氏名・メールアドレス・年齢の入力画面のThymeleafテンプレートを作成します。
[templates]で右クリック -> [新規] -> [その他] を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244937/5f924a9e-25ad-7829-17c5-a5038391bf37.png)
[新規]ダイアログで、[Web] -> [HTMLファイル] を選択して[次へ]ボタンを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244937/8554fedb-f4c7-1efc-1e0d-9979bda44fd2.png)
[新規 HTML ファイル]ダイアログで、以下を入力して[完了]ボタンを押下します。
- ファイル名：**form.html**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244937/c511d8ef-47d6-beb4-bb02-f37277c8c18e.png)

form.htmlを以下のとおり編集します。

```html:form.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
  <form th:action="@{/form}" th:object="${user}" method="post">
    <label for="name">氏名：</label>
    <input type="text" th:field="*{name}"><br>
    
    <label for="email">E-Mail：</label>
    <input type="email" th:field="*{email}"><br>
    
    <label for="age">年齢：</label>
    <input type="number" th:field="*{age}"><br>
    
    <button>送信</button>
  </form>
</body>
</html>
```
```text:参考情報
　<html xmlns:th="http://www.thymeleaf.org">・・・この宣言により、Thymeleafのタグが利用可能となる。
　th:action・・・フォームのPOST先を、@{パス名} で指定します。@{...}はリンクURL式、${...}は変数式といいます。
　th:object・・・フォームにバインドするオブジェクトを設定します。今回はコントローラ側で用意した"user"オブジェクトを設定しています。*{フィールド名}は選択変数式で、th:objectが付いたタグ内では、オブジェクト名の記述を省略できます。th:objectを使用しない場合、<input type="number" th:field="${user.age}">のように&{オブジェクト名.フィールド名}を指定する必要があります。
　th:field・・・フィールドを設定します。これは、<input>タグのid・name・value属性をHTMLに出力する機能です。<input type="text" th:field="*{name}">の記述は、<input type="text" id="name" name="name" value="">と出力されます。
```

次に確認画面のThymeleafテンプレートを作成します。
[templates]で右クリック -> [新規] -> [その他] を選択する。
[新規]ダイアログで、[Web] -> [HTMLファイル] を選択して[次へ]ボタンを押下します。
[新規 HTML ファイル]ダイアログで、以下を入力して[完了]ボタンを押下します。
- ファイル名：**confirm.html**

confirm.htmlを以下のとおり編集します。

```html:confirm.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
  <span th:inline="text">
    氏名： [[${user.name}]]<br>
  E-Mail： [[${user.email}]]<br>
   年齢： [[${user.age}]]<br>
  </span>
</body>
</html>
```
```text:参考情報
　th:inline="text"・・・タグ内のテキストを展開します。[[ ]]で囲むと、その値を表示できます。
```
# 6. Spring Bootアプリケーションの起動
[SpringMvc1Application]で右クリック -> [実行] -> [Spring Boot アプリケーション] を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244937/9bf83f1e-daab-d248-4c2a-c87043779ebc.png)
コンソールに起動メッセージが表示され、最後の行に「Completed initialization」と表示されたら起動完了。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244937/81ab4a02-450b-e595-a44a-ccfe27f04e9b.png)
ブラウザで **http://localhost:8080/form** にアクセスします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244937/7bb45436-7e51-8de8-9af5-b8f23b776312.png)
表示された画面に文字を入力し、[送信]ボタンを押下すると、入力した文字がconfirm.htmlに表示されます。

**参考書籍**
「Spring Boot 2.3 入門: 基礎から実演まで」(電子書籍)　原田 けいと／竹田 甘地／Robert Segawa著