STSでMVCに基づいたプログラムを作成してみた

## はじめに
Webアプリケーションの基本、システム開発の設計方針の１つである、MVCについてを記事にしました。

また、本記事は。下の記事で行ったプログラム作成の続きです。

https://qiita.com/ren_g/items/a57e02d7f187e8d67db2





## 前提条件

|Windows 10 64bit|
|---|
|Java 20.0.2|

## MVCとは

MVCモデルとは、M(Model)、V(View)、C(Controller)の３つに分けてWebアプリケーションなどを管理、設計する方針のことです。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526192/9bed5497-9e2b-34bf-0b16-2a15c0c752e2.png">

MVCの関係は上の画像のようになっています。

まず、ユーザーがControllerに対して要求します。
そうすると、Controllerは、ViewとModelにそれぞれ指示を出します。
この指示を受けとったViewは、画面を表示します。
また、Modelは、データベースから情報を受け取り、処理結果をControllerに送ります。
最後に、CotrollerがViewとModelから受け取った画面表示と処理結果をそれぞれユーザーに結果として送ります。


この設計方針には、メリットとデメリットがあります。

* メリット
プログラムコードがそれぞれ分かれているので、MVCの中の１つでバグが発生しても他の２つに影響はなく、被害が少なく済みます。また、バグの原因を早く見つけることが出来ます。
MVCで分けることによって、作業を分割することができます。分業によって、生産性が向上します。
* デメリット
コードをしっかりと分割できていないと、コードがわかりにくくなってしまい、作業効率が低下します。
コードを分けているので、処理速度が低下する可能性があります。

## 準備
本記事では、コントローラとビューを作成していくので、プログラムコードを編集して進めていく形になります。
よって今回は、ブランチを作成することをお勧めします。
また、ブランチについて知らない方は、私が以前書いたこの記事を読んでください。


## Controllerの作成

コントローラの作成をします。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526192/7046187c-164f-3371-e561-48b19544e52c.png">

前の記事で作成したdemoからcom.example.demoの上で右クリックします。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526192/91be1f7d-5a9f-f856-f7d4-ea5cb247f7c8.png">

右クリックしたら、新規＞その他を押します。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526192/645f2bc1-a9dd-22f2-e3cb-0f282a1fe6b7.png">

その他を押すと、この画面が表示されるので「ウィザード」の検索欄に、「クラス」と入力します。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526192/3ba2f207-efcb-7a35-61d1-00c85e9f0b93.png">

「クラス」を選択し、次へを押します。


<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526192/4322371c-433d-661b-9b7e-f10962776f56.png">

次へを押すとこの画面になります。
名前の欄に、「DemoController」と記載します。
そしたら、「完了」を押します。

次に、コントローラである、「DemoController.java」のコードを打ち込みます。
以下がコードです。
```
package com.example.demo;//パッケージに属している

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController

public class DemoController {
	@RequestMapping("/")
	String home() {
		return "Hello Spring Boot!";
	}
}

```
こちらコードは、前の記事で説明しているものになるので、説明は省きます。
また、今回はコードが変化していることを確認するために、「Hello World」ではなく、「Hello Spring Boot」と記載しています。

また、「DemoApplication.java」とコントローラを分けたので、その分「DemoApplication.java」のコードが不要になります。よって削除します。
以下がコードです。
```
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {
	
	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}
}
```
このコードも前の記事で説明済みなので省略します。
ここまでできたら実行しましょう。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526192/17c19cf5-2269-6c62-52f2-85abe92a6d9d.png">

demoを選択し、緑の矢印マーク（実行ボタン）の右にある↓を押します。
そこから、実行＞Spring Bootアプリケーションを押します。
最後に、検索ボックスに<http://localhost:8080>と入力します。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526192/2980dbcf-96ff-d1e0-cce8-921d400d0f4e.png">


この画面が表示されれば、コントローラの作成は成功となります。

## Thymeleafについて
次のステップでThymeleafを使用するので先に説明します。
Thymeleaf（タイムリーフ）とは、Spinrg boot上で動作することを前提としたオープンソフトウェアで、Javaテンプレートエンジンの１つです。
* テンプレートエンジンとは
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526192/c127fbc7-9e17-4bf8-055f-8e177dac7bb7.png">

テンプレートエンジンとは、データとテンプレートを合成して、ドキュメントを出力するソフトウェアのことです。
例えば、データから、num=10というコードを受けとって、「num」が表示されましたというテンプレートと合成したら、「１０」が表示されましたというドキュメントを出力します。
合成し、ドキュメントを出力する役割を担っているのが、テンプレートエンジンです。

* Thymeleafの利点
独自のタグを使用しないので、HTMLファイルをそのままJavaで使用することができるというメリットがあります。


## Viewの作成
コントローラの作成が終わったので、次のステップに移ります。
「DemoController」を開いて、以下のコードに書き換えます。
```
package com.example.demo;

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

@Controller
public class DemoController {
	@RequestMapping("/{num}")
	public String index(@PathVariable int num, Model model) {
		int sum = 0;
		for(int i = 1 ; i <= num ; i++) {
			sum += i;
		}
		model.addAttribute("msg", "sum=" + sum);//msgは名前、sum=は値
		return "index";
	}
}
```
この「Viewの作成」では、Thymeleafによって生成されるHTMLをレスポンスするので、アノテーションはRestControllerではなく、Controllerと記載します。
addAttributeは、第１引数と第２引数を設定することで、ビュー側から第１引数に設定した名前でデータを取りだすことが可能になります。

次にHTMLファイルを作成していきます。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526192/87efee3e-d5a0-6eee-f7dc-2c1ea8967584.png">
src/main/resourcesのtemplatesで右クリックします。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526192/f377bed7-3d11-d78f-2bfe-93e1079cd183.png">

新規＞その他を押します。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526192/835b8ab5-2bf7-b629-6fa9-09641f44d4ae.png">

一般＞ファイル＞次へを押します。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526192/6b3a8e9c-0394-9947-9678-07ef72eedb09.png">

ファイル名に、「index.html」と入力し、「完了」を押してください。
これで、HTMLファイルを作成することができました。
作成したHTMLファイルを以下のコードに書き換えます。
```
<!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title>Demo Page
            </title>
        </head>
        <body>
            <h1>Demo Page</h1>
            <p th:text="${msg}"></p>
        </body>
    </html>

```
th:text="${変数名}"で、コントローラで指定した値をビューで表示することができます。
この変数名は、addAttributeで指定した第１引数です。
画面には、第２引数で指定した値が表示されます。


次に、Thymeleafを使用するためのコードを記載していきます。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526192/6cb1c5a1-1029-077f-228d-844d2d1d5778.png">
パッケージ・エクスプローラーの下の方にあるpom.xmlを開いてください。
pom.xmlに以下のコードを書き足します。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526192/67fd34b6-c120-6eda-6f7d-ea51ba93e4a2.png">

```
　　<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
```
ここまできたら、プログラムを実行してください。
ローカルでプログラムを実行するときは、<http://localhost:8080/10>と検索してください。
この/10をいれることを忘れないようにしてください。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526192/8d548efb-ff51-ef4e-b103-40fc68a5efbe.png">
<img width="500" src="">

このように表示することができたら、成功です。

## データの入力

次は、ビューからのデータ入力を行っていきます。
Web上で入力された情報を新しくWeb上の画面に反映させるプログラムを作成していきます。
先ほど作成したindex.htmlファイルを以下のように編集します。
```
<body>
	<h1>Demo Page</h1>
	<p th:text="${msg}"></p>

	<form method="post" action="/" >
    	<input type="text" name="text1"  th:value="${value}" >
    	<input type="submit" value="実行" >
	</form>

</body>
```

また、DemoControllerも以下のように編集します。


```
package com.example.demo;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class DemoController {
	@RequestMapping(value="/", method=RequestMethod.GET)
	public ModelAndView index(ModelAndView mav) {
		mav.setViewName("index");
		mav.addObject("msg", "お名前を入力してください");
		return mav;
	}

	@RequestMapping(value="/", method=RequestMethod.POST)
	public ModelAndView send(
			@RequestParam("text1")String str,
			ModelAndView mav) {
		mav.setViewName("index");
		mav.addObject("msg", "こんにちは" + str + "さん！");
		mav.addObject("value", str);
		return mav;
	}
}
```
今回このコントローラのプログラムコードで使用したのは、Modelではなく、ModelAndViewです。
ModelAndViewとModelの違いは、利用の仕方です。
Modelは戻り値として使用しません。今作成しているビューに値を入力するようなときは、ModelAndViewを使用します。

ここまで完了したら、ローカルでプロジェクトを実行します。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526192/a67236a0-d55a-572d-1e2b-876d4361728a.png">
この画面になったら、枠の所になにか入力して。実行を押してみましょう。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526192/6059dfdb-098c-8ccb-4ad4-cd7511c9e3e3.png">
私は、「Demo」と入力したので、「こんにちはDemoさん！」と表示されました。
これで、ビューから、データを入力することが出来ました。

これで、この記事は終わりになります。
お疲れさまでした。



## 参考文献
https://www.sys-link.jp/technical/SpringBoot/SpringBoot2-1.html