회원가입 기능을 추가하려고 한다!!!! Spring Boot와 ThymeLeaf, JPA이 세가지를 동시에 사용해서 만드는 회원가입은 처음이라 서툴지만,, 열심히 해봐야지
1.오른쪽 상단에 두 버튼을 달았다. 둘다 Modal로 만들 생각이었지만 스타일의 충돌 및 기타 사유로 취소.
2. 로그인버튼에 thymeleaf를 활용하여 onclick시 location.href를 지정해준다.
<li>
<a href="#" class="button" th:onclick="|location.href='@{/signUp}'|" th:text="#{signUp}" data-toggle="modal" data-target="#signUp">Sign Up</a>
</li>
3.회원가입전용 SignUpController를 만들어 /signUp 요청이 왔을시에 회원가입 html파일로 이동시킨다
package com.project.domain.login;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequiredArgsConstructor
@RequestMapping("/signUp")
@Slf4j
public class SignUpController {
@GetMapping
public String getSignUp(Model model) {
SignUpForm signUpForm = new SignUpForm();
model.addAttribute("signUpForm", signUpForm); //기본 객체를 하나 넣어주어 thymeleaf object기능을 사용한다.
return "/login/signUp";
}
}
↓
↓
4.회원가입 Form을 위한 객체를 만든다. Bean Validation기능을 사용하기 위해
아래와 같은 의존성을 build.gradle에 추가한다.
package com.project.domain.signup;
import com.project.domain.user.SexType;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SignUpForm {
@NotBlank(message = "아이디는 필수입력 입니다.")
private String loginId;
@NotBlank(message = "사용자 이름을 입력해주세요.")
private String userName;
@NotBlank
@Pattern(regexp="^(?=.*[a-zA-Z])(?=.*\\d)(?=.*\\W).{8,20}$", message = "비밀번호는 영어와 숫자로 포함해서 8~20자리 이내로 입력해주세요.")
private String password;
@NotBlank
@Pattern(regexp="^(?=.*[a-zA-Z])(?=.*\\d)(?=.*\\W).{8,20}$", message = "비밀번호는 영어와 숫자로 포함해서 8~20자리 이내로 입력해주세요.")
private String passwordCheck;
@Email(message = "유효하지 않은 이메일입니다.")
@NotBlank(message = "이메일을 입력해주세요.")
private String email;
@NotBlank(message = "전화번호를 입력해 주세요.")
private String phone;
@NotBlank(message = "주소를 입력해 주세요.")
private String address;
@NotNull(message = "성별을 선택해주세요.")
@Enumerated(value = EnumType.STRING)
private SexType sex;
}
UserRepository에서는 User객체를 사용하지만, 김영한 선생님의 가르침에 따라 회원가입 전용 SignUpForm객체를 만들어서 사용할 예정이다.
5.회원가입 HTML을 작성한다..
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="~{/fragment/meta-fragment :: meta}"></head>
<body class="is-preload">
<div id="wrapper">
<header id="header" th:replace="~{/fragment/logoMenu-fragment :: logoMenu}"></header>
<nav id="menu" th:replace="~{/fragment/menu-fragment :: menu}"></nav>
<div id="main">
<div class="inner">
<h1 th:text="#{signUp}">회원가입</h1>
<!-- <span class="image main"><img src="images/pic13.jpg" alt="" /></span>-->
<form method="post" th:action th:object="${signUpForm}"> <!-- th:action을 입력하지않으면 현재 url(/add)로 method(POST)를 요청한다.-->
<div class="row gtr-uniform"> <!-- th:object는 빈 객체값이다. 각각의 field의 name, id 등을 넣어주기 위해, 그리고 Validation에서 튕겨나갔을시 기본 입력정보는 유지하기 위하여 사용.-->
<!--로그인 아이디-->
<div class="col-3">
<label class="signup-label" for="loginId" th:text="#{signUp.form.loginId}"></label>
</div>
<div class="col-9"> <!-- th:errorclass를 입력하면 해당 필드에서 error가 발생했을시 입력한 class를 추가해준다. 나같은 경우에는 border를 주기위해 새로 추가하였다.-->
<input class="signup-text" th:errorclass="error" type="text" name="loginId" id="loginId" th:field=*{loginId} value="" th:placeholder="#{signUp.form.loginId.placeholder}" placeholder="로그인 아이디를 입력하세요" />
<div class="signup-text-error" th:errors="*{loginId}"></div> <!-- th:errors를 사용하면 해당 필드에 에러가 있을시 bindingResult가 message를 해당 태그에 입력해준다!-->
</div>
<!--사용자 이름-->
<div class="col-3">
<label class="signup-label" for="userName" th:text="#{signUp.form.userName}"></label>
</div>
<div class="col-9">
<input class="signup-text" th:errorclass="error" type="text" name="userName" id="userName" th:field=*{userName} value="" th:placeholder="#{signUp.form.userName.placeholder}" placeholder="이름을 입력하세요" />
<div class="signup-text-error" th:errors="*{userName}"></div>
</div>
<!--비밀번호-->
<div class="col-3">
<label class="signup-label" for="password" th:text="#{signUp.form.password}"></label>
</div>
<div class="col-9">
<input class="signup-text" th:errorclass="error" type="password" name="password" id="password" th:field=*{password} value="" th:placeholder="#{signUp.form.password.placeholder}" placeholder="비밀번호를 입력하세요" />
<div class="signup-text-error" th:errors="*{password}"></div>
</div>
<!--비밀번호 확인-->
<div class="col-3">
<label class="signup-label" for="passwordCheck" th:text="#{signUp.form.passwordCheck}"></label>
</div>
<div class="col-9">
<input class="signup-text" th:errorclass="error" type="password" name="passwordCheck" id="passwordCheck" th:field=*{passwordCheck} value="" th:placeholder="#{signUp.form.passwordCheck.placeholder}" placeholder="비밀번호확인을 입력하세요" />
<div class="signup-text-error" th:errors="*{passwordCheck}"></div>
</div>
<!--이메일-->
<div class="col-3">
<label class="signup-label" for="email" th:text="#{signUp.form.email}"></label>
</div>
<div class="col-9">
<input class="signup-text" th:errorclass="error" type="text" name="email" id="email" th:field=*{email} value="" th:placeholder="#{signUp.form.email.placeholder}" placeholder="이메일을 입력하세요" />
<div class="signup-text-error" th:errors="*{email}"></div>
</div>
<!--전화번호-->
<div class="col-3">
<label class="signup-label" for="phone" th:text="#{signUp.form.phone}"></label>
</div>
<div class="col-9">
<input class="signup-text" th:errorclass="error" type="text" name="phone" id="phone" th:field=*{phone} value="" th:placeholder="#{signUp.form.phone.placeholder}" placeholder="전화번호를 입력하세요" />
<div class="signup-text-error" th:errors="*{phone}"></div>
</div>
<!--주소-->
<div class="col-3">
<label class="signup-label" for="phone" th:text="#{signUp.form.address}"></label>
</div>
<div class="col-9">
<input class="signup-text" th:errorclass="error" type="text" name="address" id="address" th:field=*{address} value="" th:placeholder="#{signUp.form.address.placeholder}" placeholder="클릭하여 주소를 선택하세요" />
<div class="signup-text-error" th:errors="*{address}"></div>
</div>
<!--성별-->
<div class="col-3">
<label class="signup-label" th:text="#{signUp.form.sex}"></label>
</div>
<div class="col-9">
<div th:each="sexType : ${sexTypes}" class="col-6">
<input type="radio" th:field="*{sex}" th:value="${sexType.name()}">
<label th:for="${#ids.prev('sex')}" th:text="${sexType.sex}"></label>
</div>
<div class="signup-text-error" th:errors="*{sex}"></div>
<!-- <div class="col-6">-->
<!-- <input type="radio" class="signup-text" th:errorclass="signup-text-error" name="sexM" id="sexM" th:field=*{sex} value="" />-->
<!-- <label class="signup-label" for="sexM" th:text="#{signUp.form.sexM}"></label>-->
<!-- </div>-->
<!-- <div class="col-6">-->
<!-- <input type="radio" class="signup-text" th:errorclass="signup-text-error" name="sexF" id="sexF" th:field=*{sex} value="" />-->
<!-- <label class="signup-label" for="sexF" th:text="#{signUp.form.sexF}"></label>-->
<!-- </div>-->
</div>
</div>
<div style="width:50%;margin:0 auto;">
<ul class="actions fit">
<li><button type="submit" class="button fit" th:text="#{signUp}">회원가입</button></li>
<li><button type="button" th:onclick="|location.href='/'|" class="button fit" th:text="#{goHome}">홈으로</button></li>
</ul>
</div>
</form>
</div>
</div>
<footer id="footer" th:replace="~{/fragment/contactMe-fragment :: contactMe}"></footer>
</div>
<div th:replace="~{fragment/script-fragment :: script}"></div>
</body>
</html>
.
@ModelAttribute("sexTypes")
public SexType[] sexTypes(){
return SexType.values();
}
위 기능을 사용하여 sexTypes이라는 이름으로 View화면으로 전송하였고 해당 html을 손쉽게 그릴 수 있었다.
<div th:each="sexType : ${sexTypes}" class="col-6">
<input type="radio" th:field="*{sex}" th:value="${sexType.name()}">
<label th:for="${#ids.prev('sex')}" th:text="${sexType.sex}"></label>
</div>
'프로젝트[종료]' 카테고리의 다른 글
13. 로그인 사용자 Session 처리하기 (0) | 2023.04.28 |
---|---|
12.회원가입 기능 만들기(2) (2) | 2023.04.27 |
10. JpaRepository<T, Id>인터페이스 상속받기 (0) | 2023.04.26 |
9. JPA를 사용하여 SpringBoot와 MariaDB연동하기 (0) | 2023.04.20 |
8. ThymeLeaf의 fragment기능 이용하기 (0) | 2023.04.18 |