【Java・SpringBoot・Thymeleaf】ログイン・新規登録画面作成（SpringBootアプリケーション実践編1）


**ログインをして、ユーザー一覧を表示するアプリケーションを作成**し、
Springでの開発について勉強していきます🌟

#まずはコントローラーと画面を作成
* **ログインボタン**を押すと、何も処理をせずにログイン画面に戻る
* **新規登録はこちら**をクリックすると、ユーザー登録画面に遷移
* **ユーザー登録ボタン**を押すと、何も処理をせずにログイン画面に戻る

ような機能を先に作ります

##ログインコントローラー
* GETメソッド、POSTメソッドでHTTPリクエストが来たら、login.htmlに遷移する
* returnに指定するhtmlファイルは、`src/main/resources/templates`からの相対パス
    * `src/main/resources/templates/login/login.html`を指定

```LoginController.java
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

@Controller
public class LoginController {

    //GETメソッド
    @GetMapping("/login")
    public String getLogin(Model model) {
        //login.htmlに画面遷移
        return "login/login";
    }

    //POSTメソッド
    @PostMapping("/login")
    public String postLogin(Model model) {
        return "login/login";
    }
}
```

##ログイン画面
###headで**Bootstrap、JQuery**を読み込む
* 先にJQueryを読み込んでからBootstrapのjsを読み込む

###Thymeleafで**css/jsファイルを読み込む**時の属性
* `th:href="@{<resources配下からの相対パス>}"`
* `th:src="@{<resources配下からの相対パス>}"`

###Thymelwafでアンカータグを使う
* `th:href=`で@GetMappingの文字列を指定
* HTTPリクエストはGETメソッドで送信
    *  `<a th:href="@{'/signup'}">新規登録はこちら</a>`


```login.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"></meta>
    <link th:href="@{/webjars/bootstrap/3.3.7-1/css/bootstrap.min.css}" rel="stylesheet"></link>
    <script th:src="@{/webjars/jquery/1.11.1/jquery.min.js}"></script>
    <script th:src="@{/webjars/bootstrap/3.3.7-1/js/bootstrap.min.js}"></script>

    <title>Login</title>
</head>
<body class="text-center">
    <h1>Login</h1>
    <form method="post" action="/login">
        <label>ユーザーID</label>
        <input type="text" /><br/>
        <br />
        <label>パスワード</label>
        <input type="password" /><br/>
        <br />
        <button class="btn btn-primary" type="submit">ログイン</button>
    </form>
    <br />
    <a th:href="@{'/signup'}">新規登録はこちら</a>
</body>
</html>
```

##新規登録コントローラー
###Thymeleafでラジオボタンの値を動的に変更
* Mapを用意しそのMapに入ったキーと値を画面に表示する
    * initRadioMarrige()というメソッドでMapに値を入れる
    * ユーザー登録画面にGETリクエストが来たら、ModelクラスにMapを登録
    * →**画面からMapの値を取得できるようになる!**

```java
// ラジオボタンの初期化メソッド呼び出し
radioMarriage = initRadioMarrige(); 
// ラジオボタン用のMapをModelに登録
model.addAttribute("radioMarriage", radioMarriage);
```

###リダイレクト
* メソッドの返却値に`redirect:<遷移先パス>`指定
    * `return "redirect:/login";`
* リダイレクトすると、遷移先のControllerクラスのメソッドが呼ばれ**GETメソッドでHTTPリクエストが送られる**
    * LoginControllerのgetLoginメソッドが呼び出される
        * /signupにGETメソッドでHTTPリクエスト→signup.htmlに遷移
        * /signupにPOSTメソッドでHTTPリクエスト→ログイン画面にリダイレクト

```SignupController.java
import java.util.LinkedHashMap;
import java.util.Map;

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

@Controller
public class SignupController {

    //ラジオボタン用変数
    private Map<String, String> radioMarriage;

    //ラジオボタン初期化
    private Map<String, String> initRadioMarrige() {

        Map<String, String> radio = new LinkedHashMap<>();

        // 既婚、未婚をMapに格納
        radio.put("既婚", "true");
        radio.put("未婚", "false");

        return radio;
    }

    @GetMapping("/signup")
    public String getSignUp(Model model) {

        // ラジオボタンの初期化メソッド呼び出し
        radioMarriage = initRadioMarrige();

        // ラジオボタン用のMapをModelに登録
        model.addAttribute("radioMarriage", radioMarriage);

        // signup.htmlに画面遷移
        return "login/signup";
    }

    @PostMapping("/signup")
    public String postSignUp(Model model) {

        // login.htmlにリダイレクト
        return "redirect:/login";
    }
}
```

##新規登録画面
###ラジオボタンの実装
* **th:each属性：拡張for文のようにModelに登録されている値が繰り返し呼ばれる**
    * `th:each="<変数名>:${<ModelAttributeのキー名>}"`
        * `<div th:each="item : ${radioMarriage}">`
    * th:eachタグ内では、**Modelに登録されている値を変数名で取得できる**
        * th:each属性のdivタグの中では、itemという変数を使うことができる
        * itemの中身はSignupControllerクラスで取得したMapが入っている

```html
<div th:each="item : ${radioMarriage}">
    <input type="radio" name="radioMarrige"
         th:text="${item.key}"
         th:value="${item.value}">
    </input>
</div>
```

* **th:text：画面に表示される文字列を指定**
    * `th:text="${item.key}`
        * 上の例ではMapクラスのkeyの値（既婚/未婚）を画面に表示
* **th:value：画面からControllerクラスに送る値を指定**
    * `th:value="${item.value}`
        * 上の例ではMapクラスのvalue（true/false）を送る




```signup.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"></meta>

    <!-- Bootstrapの設定 -->
    <link th:href="@{/webjars/bootstrap/3.3.7-1/css/bootstrap.min.css}" rel="stylesheet"></link>
    <script th:src="@{/webjars/jquery/1.11.1/jquery.min.js}"></script>
    <script th:src="@{/webjars/bootstrap/3.3.7-1/js/bootstrap.min.js}"></script>

    <title>SignUp</title>
</head>
<body>
    <div class="col-sm-5">
        <div class="page-header">
            <h1>ユーザー登録画面</h1>
        </div>
        <form method="post" th:action="@{/signup}">
            <table class="table table-bordered table-hover">
                <!-- ユーザーID -->
                <tr>
                    <th class="active col-sm-3">ユーザID</th>
                    <td>
                        <div class="form-group">
                            <input type="text" class="form-control" />
                        </div>
                    </td>
                </tr>
                <!-- パスワード -->
                <tr>
                    <th class="active">パスワード</th>
                    <td>
                        <div class="form-group">
                            <input type="text" class="form-control" />
                        </div>
                    </td>
                </tr>
                <!-- ユーザー名 -->
                <tr>
                    <th class="active">ユーザー名</th>
                    <td>
                        <div class="form-group">
                            <input type="text" class="form-control" />
                        </div>
                    </td>
                </tr>
                <!-- 誕生日 -->
                <tr>
                    <th class="active">誕生日</th>
                    <td>
                        <div class="form-group">
                            <input type="text" class="form-control" placeholder="yyyy/MM/dd" />
                        </div>
                    </td>
                </tr>
                <!-- 年齢 -->
                <tr>
                    <th class="active">年齢</th>
                    <td>
                        <div class="form-group">
                            <input type="text" class="form-control" />
                        </div>
                    </td>
                </tr>
                <!-- 結婚 -->
                <tr>
                    <th class="active">結婚</th>
                    <td>
                        <div class="form-group">
                            <div th:each="item : ${radioMarriage}">
                                <input type="radio" name="radioMarrige"
                                    th:text="${item.key}"
                                    th:value="${item.value}">
                                </input>
                            </div>
                        </div>
                    </td>
                </tr>
            </table>

            <button class="btn btn-primary" type="submit">ユーザー登録</button>
        </form>
    </div>
</body>
</html>
```

##SpringBootを起動して、ログイン画面を確認！
* http://localhost:8080/login
* **ログインボタン**を押しても、何も処理をせずにログイン画面に戻る
* **新規登録はこちら**をクリックすると、ユーザー登録画面に遷移
* **ユーザー登録ボタン**を押すと、何も処理をせずにログイン画面に戻る
ことが確認できましたo(^_^)o
* 次はデータバインドを実装します


![login.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282755/52ad48ae-a156-fd33-4e0a-08ce74ef427b.png)


![signup.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282755/4dc8b5aa-b1ba-3015-1cbb-8349301b8c1b.png)