新入社員研修用にWebアプリを作ろうとしているお話【Spring Bootでページを作る話】

[前回](https://qiita.com/mickie895/items/5b9656cc73fefda768d2)の続き。
今回はとりあえず実装したじゃんけんの画面を実装してみる。

# 参考文献

今回は下記の書籍を参考にして画面を実装した。

https://www.amazon.co.jp/gp/product/B08XPBPH9C/ref=ppx_yo_dt_b_d_asin_title_o00?ie=UTF8&psc=1

あまりに単純すぎたか、現状では最初の数十ページしか参考にしていない。

# WebGUIの実装に向けて

とりあえず、現時点ですべきことを列挙してみる。
今はデータベースは使っていないので、こんな感じだろう。

## WebGUIの(現時点での)ToDoリスト

+ [ ] じゃんけんを行う画面の実装
  + [ ] じゃんけん前の画面の実装
  + [ ] 勝敗を表示する画面の実装

# じゃんけんを行う画面の実装

書き忘れていたが、このプロジェクトはWindows上で、Eclipse IDEにSpling tools4をインストールした環境で開発している。
他の開発環境やOSであれば適宜読み替えてほしい。

なお、~~面倒だったから~~英語のトラブルシューティングにあたっても大丈夫なように日本語化はしていない。

## プロジェクトの設定

まずは現時点で必要なspring bootの設定を列挙してみよう。

<dl>
  <dt>Spring web</dt>
  <dd>webページを表示するために必要</dd>
  <dt>Thymeleaf</dt>
  <dd>じゃんけんの結果を表示するために、値をページに紐付ける必要がある</dd>
</dl>

どうやらspring bootで一度プロジェクトを作ってしまえば後で設定を変えることができるみたいなので、
プロジェクトを右クリックしてから下記のスクリーンショットのように選択して、上記のライブラリを追加した。

![プロジェクト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395414/01441faf-a4cf-cc8c-0f93-b471f29be623.png)

## HTMLの実装

まずはHTMLの実装……の前に、プロジェクト全体のエンコーディングをUTF-8に変更しておこう。
Thymeleafを使用し、HTMLを書き換えるのに使うエンコーディングはUTF-8のようなので、
動作確認の時点で慌ててエンコーディングを変更する羽目になる(なった)。

![エンコーディング選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395414/3233d3b0-e95d-9c6f-821e-32f96933413c.png)
プロジェクトを右クリック、もしくはAlt+Enterでプロパティを表示し、テキストファイルのエンコーディングをUTF-8を指定しよう。

そしてsrc/main/resources/templatesの直下に次のようなHTMLを持つindex.htmlを作った。

<details>
<div>

```html:index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"></meta>
<title>練習用じゃんけんアプリケーション</title>
</head>
<body>

<h1>じゃんけんしましょう</h1>

下記の3つのボタンからどれか選んでね。

<hr>

<table><td>
<form method="post" action="/result">
<input type="hidden" name="hand" value="1">
<input type="submit" value="グーを出す">
</form></td><td>
<form method="post" action="/result">
<input type="hidden" name="hand" value="2">
<input type="submit" value="チョキを出す">
</form></td><td>
<form method="post" action="/result">
<input type="hidden" name="hand" value="3">
<input type="submit" value="パーを出す">
</form></td></table>

</body>
</html>

```
</div>
</details>

全部のボタンは同じコードを実行するけど、「hidden」を持つインプットフォームにじゃんけんの手のデータをもたせる事により、
プレイヤーの手を認識できるようにしてある。

このボタンを押した先のhtmlもstart/result.htmlに実装する。
参考文献をもとにページを作っているため、若干フォルダの切り方がおかしくなっている気もするが気にしないでおく。

<details>
<div>

```html:result.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"></meta>
<title>練習用じゃんけんアプリケーション</title>
</head>
<body>
<h1>じゃんけんぽん</h1>
<hr>
あなたの手は<div th:text="${player}"></div>、コンピュータの手は<div th:text="${cpu}"></div>
<p>
結果は<div th:text="${result}"></div>です。
</p>
<hr>
<a href="./start">もう一回行う</a>
</body>
</html>

```
</div>
</details>

## コントローラの実装

画面は実装できたから、それを制御するコードを実装する。
適当にクラス名はJankenControllerとしよう。

そして「依存性の注入」とやらでJankenModelを紐付け……する必要が無いなこれ。JankenModelのインスタンスを結果画面以外で使わないな。
勝敗履歴の表示や蓄積もページを跨いでインスタンスを持っておく必要がまったくないから、そのような機能は次の課題にしておくか。

ということで、各画面ごとの処理を実装したのがこちら。

<details>
<div>

```java:JankenController.java
package personal.mickie.janken;

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

import personal.mickie.janken.Model.JankenHands;
import personal.mickie.janken.Model.JankenModel;
import personal.mickie.janken.Model.JankenResult;

@Controller
public class JankenController {
	
@GetMapping(value="/start")
	public String startPage() {
		return "index";
	}

@PostMapping("/result")
	public String postHand(@RequestParam("hand") int hand_code, Model model) {
		JankenModel cpu = new JankenModel();
		JankenHands player = JankenHands.GetHandFromCode(hand_code);
		
		cpu.setCpuHand();
		
		JankenResult result = cpu.checkResult(player);
	
		model.addAttribute("cpu", cpu.getCpuHandName());
		model.addAttribute("player", player.getHandName());
		model.addAttribute("result", result.toString());
		
		return "start/result";
	}
	
}

```
</div>
</details>

参考文献を読んでいたら特にいうべきことも無いと思う。

# 動作確認

プロジェクトをビルド、実行して、
`http://localhost:8080/start`にアクセスすれば下記画面にアクセスできる。
ちょっと懐かしさを感じるシンプルさですね。
![じゃんけん1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395414/81d89992-459d-394e-1ff2-41e9b05e6860.png)

もちろんボタンをクリックすれば結果が出る。
無駄に改行されてしまっているのは20年前のHTMLの知識を使ってしまっているからだろう。ちょっと調べておきます。

![結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395414/ed9954af-97ac-744b-faf9-9fb6a0c92506.png)

ソースコードはここに保存してあります。

https://github.com/mickie895/JankenApp

# 現状のToDoリストと次回の更新予定

今までの実装状況はこんな感じ。次はとりあえずデータベース周りをどうにかしようか。

## じゃんけんのToDoリスト

+ [x] じゃんけんを行う
  + [x] CPUの手をセットする
    + [x] 数字を指定すれば対応する手になる
    + [x] 数字を指定しなければランダムに出す
  + [x] プレイヤーの手をセットする
    + [x] じゃんけんの3すくみを行う
    + [x] あいこを実装する
+ [ ] ~~ヘルプを表示する~~単純だからいらないかな？
+ [x] 3つの手があることをわかるようにする
+ [ ] 過去の勝率を表示する
  + [ ] 通算成績を表示する
  + [ ] 最近10戦を表示する

## WebGUIのToDoリスト

+ [x] じゃんけんを行う画面の実装
  + [x] じゃんけん前の画面の実装
  + [x] 勝敗を表示する画面の実装
+ [ ] 過去の勝率を表示する画面の実装
+ [ ] 何らかの画面をまたぐ要素の実装を行う
  + [ ] 次に出す手の予告機能とか？