見出し画像

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」

こんな感じの構成です

画像3

◆コントローラ作る
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; //結婚ステータス
	
}


画像1

まだ途中…!!

最後まで行ったら、記事分けたり再編集もするかもです。

もしも気に入ったら、サポートお願いします! おやつを買いますので、餌付けができます。