Springフレームワーク07:ユーザー登録ページつくってみよう(手順)
【ログイン画面サンプルを作るよ!】
◆BootStrap、jQueryを設定する(webjars)
POM(Project Object Model)ファイル
pom.xmlに追記(org.projectlombokの下から)
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.3.1-1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>4.2.1</version>
</dependency>
プロジェクト名 > 右クリック > Maven > プロジェクトの更新
下の3つのチェックボックスにチェック入ってることを確認 > OK
☑pom…
☑ローカル…
☑オブジェクト…
Maven依存関係 > エラー出ていなければOK
◆まずパッケージ作る
src/main/java > 右クリック > 新規 > 名前:「com. example. demo. login. controller」
こんな感じの構成です
◆コントローラ作る
com.example.demo.login.controller > 右クリック > 新規 > クラス > 名前:LoginController
package com.example.demo.login.controller;
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 {
@GetMapping("/login")
public String getLogin(Model mode) {
return "login/login";
}
@PostMapping("/login")
public String postLogin(Model model) {
// ログイン画面login.htmlに遷移
return "login/login";
}
}
◆サインアップコントローラ作る
com.example.demo.login.controller > 右クリック > 新規 > クラス > 名前:SignupController
※ thymeleafでラジオボタンを使う場合は、Mapに選択肢とフラグをまとめて入れる
※ BindingResult
import org.springframework.validation.BindingResult;
フレームワークのバリデーションをインポート
package com.example.demo.login.controller;
import java.util.LinkedHashMap;
import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
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.login.domain.model.GroupOrder;
import com.example.demo.login.domain.model.SignupForm;
@Controller
public class SignupController {
//ラジオボタン用の変数
private Map<String, String> radioMarriage;
//ラジオボタンの初期化
private Map<String, String> initRadioMarriage() {
Map<String, String> radio = new LinkedHashMap<>();
//既婚、未婚をMapに格納
radio.put("既婚", "true");
radio.put("未婚", "false");
return radio;
}
@GetMapping("/signup")
public String getSignUp(@ModelAttribute SignupForm form, Model model) {
//ラジオボタンの初期化メソッド呼び出し
radioMarriage = initRadioMarriage();
//ラジオボタン用のMapをmodelに登録
model.addAttribute("radioMarriage", radioMarriage);
//signup.hrmlに画面遷移
return "login/signup";
}
@PostMapping("/signup")
//public String postSignUp(Model model) {
public String postSignUp(@ModelAttribute("signupForm") @Validated(GroupOrder.class) SignupForm form, BindingResult bindingResult, Model model) {
//bindingResult.hasErrors()メソッドで入力チェックにひっかかった場合
if(bindingResult.hasErrors()) {
//GETリクエスト用のメソッドを呼び出して、ユーザ登録画面に戻る
return getSignUp(form, model);
}
//formの中身をコンソールに出して確認する
System.out.println(form);
//login.htmlにリダイレクト
return "redirect:/login";
}
}
◆まずフォルダ作る
src/main/resources/templates > 右クリック > 新規 > フォルダ > 名前:login
◆ログイン画面作る
> 右クリック > 新規 > ファイル > 名前:login.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"></meta>
<!-- Bootstrapの設定 -->
<link th:href="@{/webjars/bootstrap/4.2.1/css/bootstrap.min.css}" rel="stylesheet"></link>
<script th:src="@{/webjars/jquery/3.3.1-1/jquery.min.js}"></script>
<script th:src="@{/webjars/bootstrap/4.2.1/js/bootstrap.min.js}"></script>
<title>Login</title>
</head>
<body class="text-center">
<h1>Login</h1>
<form method="post" action="/login">
<!-- ユーザーID -->
<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>
◆サインアップ画面作る
> 右クリック > 新規 > ファイル > 名前:signup.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"></meta>
<!-- Bootstrapの設定 -->
<link th:href="@{/webjars/bootstrap/4.2.1/css/bootstrap.min.css}" rel="stylesheet"></link>
<script th:src="@{/webjars/jquery/3.3.1-1/jquery.min.js}"></script>
<script th:src="@{/webjars/bootstrap/4.2.1/js/bootstrap.min.js}"></script>
<title>SignUp</title>
</head>
<body>
<div class="col-sm-12">
<div class="text-center page-header">
<h1>ユーザー登録画面</h1>
</div>
<form method="post" th:action="@{/signup}" th:object="${signupForm}">
<table class="table table-bordered table-hover">
<!-- ユーザーIDの入力エリア -->
<tr>
<th class="active">ユーザーID <span class="badge badge-danger">必須</span></th>
<td>
<div class="form-group col-sm-12" th:classappend="${#fields.hasErrors('userId')} ? 'is-invalid'">
<input Type="text" class="form-control" th:field="*{userId}"/>
<span class="text-danger"
th:if="${#fields.hasErrors('userId')}"
th:errors="*{userId}">
user ID error
</span>
</div>
</td>
</tr>
<!-- パスワードの入力エリア -->
<tr>
<th class="active">パスワード <span class="badge badge-danger">必須</span></th>
<td>
<div class="form-group col-sm-12" th:classappend="${#fields.hasErrors('password')} ? 'is-invalid'">
<input Type="text" class="form-control" th:field="*{password}"/>
<span class="text-danger"
th:if="${#fields.hasErrors('password')}"
th:errors="*{password}">
user ID error
</span>
</div>
</td>
</tr>
<!-- ユーザー名の入力エリア -->
<tr>
<th class="active">ユーザー名 <span class="badge badge-danger">必須</span></th>
<td>
<div class="form-group col-sm-12" th:classappend="${#fields.hasErrors('userName')} ? 'is-invalid'">
<input Type="text" class="form-control" th:field="*{userName}"/>
<span class="text-danger"
th:if="${#fields.hasErrors('userName')}"
th:errors="*{userName}">
userName error
</span>
</div>
</td>
</tr>
<!-- 誕生日の入力エリア -->
<tr>
<th class="active">誕生日 <span class="badge badge-danger">必須</span></th>
<td>
<div class="form-group col-sm-12" th:classappend="${#fields.hasErrors('birthday')} ? 'is-invalid'">
<input Type="text" class="form-control" placeholder="yyyy/MM/dd" th:field="*{birthday}"/>
<span class="text-danger"
th:if="${#fields.hasErrors('birthday')}"
th:errors="*{birthday}">
birthday error
</span>
</div>
</td>
</tr>
<!-- 年齢の入力エリア -->
<tr>
<th class="active">年齢 <span class="badge badge-danger">必須</span></th>
<td>
<div class="form-group col-sm-12" th:classappend="${#fields.hasErrors('age')} ? 'is-invalid'">
<input Type="text" class="form-control" th:field="*{age}"/>
<span class="text-danger"
th:if="${#fields.hasErrors('age')}"
th:errors="*{age}">
age error
</span>
</div>
</td>
</tr>
<!-- 未婚既婚の入力エリア -->
<tr>
<th class="active">結婚 <span class="badge badge-danger">必須</span></th>
<td>
<div class="form-group col-sm-12" th:classappend="${#fields.hasErrors('marriage')} ? 'is-invalid'">
<div th:each="item : ${radioMarriage}">
<input type="radio" name="radioMarriage"
th:text="${item.key}"
th:value="${item.value}"
th:field="*{marriage}"/>
</div>
<span class="text-danger"
th:if="${#fields.hasErrors('marriage')}"
th:errors="*{marriage}">
age error
</span>
</div>
</td>
</tr>
</table>
<!-- エラーメッセージの一覧表示 -->
<!--
<ul>
<li th:each="error : ${#fields.detailedErrors()}">
<span th:text="${error.message}">Error message</span>
</li>
</ul>
-->
<!-- ユーザー登録ボタン -->
<button class="btn btn-primary btn-lg btn-block" type="submit">ユーザー登録</button>
</form>
</div>
</body>
</html>
【データバインド】
画面の入力項目←→オブジェクトのフィールド(SignupForm.java)
マッピング
src/main/javaの下に
com.example.demo.login.domain.modelパッケージを作る
その下に新規クラス SignupForm.javaを作る
package com.example.demo.login.domain.model;
import java.util.Date;
import javax.validation.constraints.AssertFalse;
import javax.validation.constraints.Email;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import org.hibernate.validator.constraints.Length;
import org.springframework.format.annotation.DateTimeFormat;
import lombok.Data;
@Data
public class SignupForm {
//@NotBlank
//パターン5以外↑
@NotBlank(groups = ValidGroup1.class, message="{require_check}")
//@Email
//パターン5以外↑
@Email(groups = ValidGroup2.class, message="{email_check}")
private String userId; //ユーザーID
//@NotBlank
//パターン5以外↑
@NotBlank(groups = ValidGroup1.class, message="{require_check}")
//@Length(min = 4, max = 100)
//パターン5以外↑
@Length(groups = ValidGroup2.class, min = 4, max = 100, message="{length_check}")
//@Pattern(regexp = "^[a-zA-Z0-9]+$")
//パターン5以外↑
@Pattern(regexp = "^[a-zA-Z0-9]+$", groups = ValidGroup3.class, message="{pattern_check}")
private String password; //パスワード
//@NotBlank
//パターン5以外↑
@NotBlank(groups = ValidGroup1.class,message="{require_check}")
private String userName; //ユーザー名
//@NotNull
//パターン5以外↑
@NotNull(groups = ValidGroup1.class, message="{require_check}")
@DateTimeFormat(pattern = "yyyy/MM/dd")
private Date birthday; //誕生日
//@Min(20)
//パターン5以外↑
@Min(groups = ValidGroup2.class, value=20, message="{min_check}")
//@Max(100)
//パターン5以外↑
@Max(groups = ValidGroup2.class, value=100, message="{max_check}")
private int age; //年齢
//@AssertFalse
//パターン5以外↑
@AssertFalse(groups = ValidGroup2.class, message="{false_check}")
private boolean marriage; //結婚ステータス
}
まだ途中…!!
最後まで行ったら、記事分けたり再編集もするかもです。