본문 바로가기

SpringBoot

SpringBoot(22) - 복습 예제(회원가입 시 ID 중복 체크)

728x90
반응형

1) SpringBoot

   1-1) 복습 예제

      1-1-1) 회원가입 시 ID 중복 체크 기능 구현

 

 

 

 

 

1) SpringBoot

1-1) 복습 예제

1-1-1) 회원가입 시 ID 중복 체크 기능 구현

(1) [src/main/resources] - [templates.memberView] 안에 joinForm.html 파일 생성 후 아래와 같이 작성

<!DOCTYPE html>
<html xmlns:th="http://thymeleaf.org"
	xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
	<meta charset="UTF-8">
	<title>회원가입</title>
	<style>
		#joinArea {
			width: 700px;
			margin: 0 auto;
			text-align: center;
		}
		
		#joinForm {
			display: flex;
			flex-direction: column;
			justify-content: center;
		}
		
				
		#formArea {
			display: flex;
			justify-content: center;
		}
		
		table, tr, td {
			border: 2px solid black;
        	border-collapse: collapse;
        	padding: 10px;
        	margin: 20px 0 15px 0;
		}
		
		th {
			width: 100px;
			background-color: grey;
			color: white;
		}
		
		td {
			width: 300px;
			text-align: left;
		}
		
		#idCheckBtn {
			margin-left: 20px;
		}
		
		td > .memberInfo {
			height: 25px;
		}
		
		#pwInputCol > div {
			height: 10px;
		}
		
		td > #address {
			width: 260px;
			height: 25px;
		}
		
	</style>
	<script th:src="@{/js/jquery-3.7.1.min.js}"></script>
	<script>
	$(document).ready(function() {
		$("#joinForm").submit(check);
		$("#idCheckBtn").click(winOpen);
		// $("#idCheckBtn").on("click", winOpen);
	});
	
	function check() {
		let id = $("#memberId").val();
		let pw = $("#memberPassword").val();
		let pw2 = $("#memberPwCheck").val();
		let name = $("#memberName").val();
		
		if (id.length < 3 || id.length > 10) {
			alert("ID는 3자 이상 10자 이하의 글자를 반드시 입력해주세요!!");
			$("#memberId").focus();
			$("#memberId").val('');
			
	        return false;
		}
		
		if (pw.length < 8 || pw.length > 12) {
			alert("비밀번호는 8자 이상 12자 이하의 글자를 반드시 입력해주세요!!");
			$("#memberPassword").focus();
			$("#memberPassword").val('');
			
	        return false;
		}
		
		if (pw != pw2) {
			alert("입력하신 비밀번호가 일치하지 않습니다.\n확인 후 다시 입력해주세요!!");
			$("#memberPwCheck").focus();
			$("#memberPwCheck").val('');
			
	        return false;
		}
		
		if (name.length == 0) {
			alert("이름은 반드시 입력해주세요!!");
			$("#memberName").focus();
			$("#memberName").val('');
			
	        return false;
		}
		
		return true;
		
	}
	
	function winOpen() {
		// window.open() : 새창을 띄우는 역할을 함
		let w = window.open('idCheck', 'win', 'left=500,top=200,width=500,height=400,location=no');
	}
	
	</script>
</head>
<body>
	<div id="joinArea">
		<h1>[ 회원가입 ]</h1>
		<form th:action="@{/member/join}" method="post" id="joinForm">
			<div id="formArea">
				<table>
					<tr>
						<th>
							<label for="memberId">ID</label>
						</th>
						<td>
							<input type="text" name="memberId" id="memberId" class="memberInfo" placeholder="ID 중복확인 이용" readonly="readonly" />
							<input type="button" id="idCheckBtn" value="ID 중복확인">
						</td>
					</tr>
					<tr>
						<th>
							<label for="memberPassword">비밀번호</label>
						</th>
						<td id="pwInputCol">
							<input type="password" name="memberPassword" id="memberPassword" class="memberInfo" placeholder="비밀번호 입력" />
							<br>
							<div></div>
							<input type="password" id="memberPwCheck" class="memberInfo" placeholder="비밀번호 다시 입력" />
						</td>
					</tr>
					<tr>
						<th>
							<label for="memberName">이름</label>
						</th>
						<td>
							<input type="text" name="memberName" id="memberName" class="memberInfo" placeholder="이름 입력" />
						</td>
					</tr>
					<tr>
						<th>
							<label for="email">이메일</label>
						</th>
						<td>
							<input type="text" name="email" id="email" class="memberInfo" placeholder="이메일 입력" />
						</td>
					</tr>
					<tr>
						<th>
							<label for="phone">전화번호</label>
						</th>
						<td>
							<input type="text" name="phone" id="phone" class="memberInfo" placeholder="전화번호 입력" />
						</td>
					</tr>
					<tr>
						<th>
							<label for="address">주소</label>
						</th>
						<td>
							<input type="text" name="address" id="address" placeholder="주소 입력" />
						</td>
					</tr>
				</table>
			</div>
			
	        <div id="btnArea">
	        	<input type="submit" value="가입" />
	        	<input type="reset" value="다시 쓰기" />
	        </div>
		</form>
	</div>
</body>
</html>

 

 

(2) [src/main/resources] - [templates.memberView] 안에 idCheck.html 파일 생성 후 아래와 같이 작성

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ID 중복 확인</title>
<style>
	#idCheckArea {
		width:300px;
		margin:0 auto;
		text-align:center;
	}
</style>
<script th:src="@{/js/jquery-3.7.1.min.js}"></script>
<script>
	$(document).ready(function() {
		$("#inputButton").click(function() {
			let id = $(this).data("id");
			// let id = $(this).attr("data-id");
			
			// $(opener.document) : 자신을 열어준 부모 창을 가리킴
			$(opener.document).find("#memberId").val(id);
			// opener.document.getElementById("id").value = id;
			
			window.close();
		});
	});
</script>
</head>
<body>
	<div id="idCheckArea">
		<h1>[ ID 중복 확인 ]</h1>
		
		<form id="searchForm" action="idCheck" method="post">
			<span>검색할 ID</span>
			<input type="text" name="searchId" id="searchId">
			<input type="submit" value="검색">
		</form>
		
		<!-- 검색한 후에만 출력 -->
		<div th:if="${searchId != null}" id="idCheckResult">
			<!-- 사용 가능한 경우에만 출력 -->
			<div th:if="${result}">
				<p>
					<span th:text="${searchId}"></span>
					<span> : 사용 가능한 ID입니다.</span>
				</p>
				<p>
					<input type="button" value="ID 사용하기"
					id="inputButton" th:data-id="${searchId}">
				</p>
			</div>
			
			<!-- 사용 불가능한 경우에만 출력 -->
			<div th:if="${not result}">
				<p>
					<span th:text="${searchId}"></span>
					<span> : 이미 사용중인 ID입니다.</span>
				</p>
			</div>
		</div>
		
	</div>
</body>
</html>

 

 

(3) [src/main/java] - [net.datasa.web5.service] 안에 MemberService.java 파일 생성 후 아래와 같이 작성

package net.datasa.web5.service;

import org.springframework.stereotype.Service;

import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import net.datasa.web5.domain.dto.MemberDTO;
import net.datasa.web5.domain.entity.MemberEntity;
import net.datasa.web5.repository.MemberRepository;

/**
 * 회원정보 관련 처리 서비스
 * */

@RequiredArgsConstructor
@Service
@Transactional
public class MemberService {
	private final MemberRepository memberRepository;

	/**
	 * 가입 처리
	 * */
	public void memberJoin(MemberDTO dto) {
		MemberEntity entity = MemberEntity.builder()
				// DTO로 전달받은 값들을 Entity에 세팅
				.memberId(dto.getMemberId())
				.memberPassword(dto.getMemberPassword())
				.memberName(dto.getMemberName())
				.email(dto.getEmail())
				.phone(dto.getPhone())
				.address(dto.getAddress())
				// 기타 추가 데이터를 Entity에 세팅
				.enabled(true)
				.rolename("ROLE_USER")
				.build();
		
		// DB에 저장
		memberRepository.save(entity);
		
	}

	/**
	 * 전달받은 아이디를 DB에서 조회하여 사용중인지 여부 리턴
	 * @param searchId 조회할 아이디
	 * @return 있으면 사용불가 false, 없으면 사용가능 true
	 * */
	public boolean idCheck(String searchId) {
		
		return !memberRepository.existsById(searchId);
		
		/**
		 * // 바로 위의 코드와 동일한 기능을 수행하는 코드이다.
		 * // findById() : Primary Key 기준으로 검색을 하는 메서드(findById() : Optional 객체를 반환함)
		 * // orElse(null) : 결과가 없으면 "null" 값을 대입하는 메서드
		 * if (memberRepository.findById(searchId).isPresent()) {
			return false;
		} else {
			return true;
		}
		*/
		
	}

}

 

 

(4) [src/main/java] - [net.datasa.web5.controller] 안에 MemberController.java 파일 생성 후 아래와 같이 작성

package net.datasa.web5.controller;

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

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.datasa.web5.domain.dto.MemberDTO;
import net.datasa.web5.service.MemberService;

/**
 * 회원정보 관련 Controller
 * */

@Slf4j
@RequestMapping("member")
@RequiredArgsConstructor
@Controller
public class MemberController {
	private final MemberService memberService;
	
	/**
	 * 회원가입 양식으로 이동
	 * */
	@GetMapping("joinForm")
	public String join() {
		return "memberView/joinForm";
	}
	
	@PostMapping("join")
	public String join(@ModelAttribute MemberDTO member) {
		log.debug("전달된 회원정보 : {}", member);
		
		// 서비스로 전달하여 저장
		memberService.memberJoin(member);
		
		return "redirect:/";
	}
	
	@GetMapping("idCheck")
	public String idCheck() {
		return "memberView/idCheck";
	}
	
	@PostMapping("idCheck")
	public String idCheck(
			@RequestParam("searchId") String searchId,
			Model model) {
		// ID 중복확인 폼에서 전달된 검색할 아이디를 받아서 log 출력
		log.debug("전달된 검색 ID : {}", searchId);
		
		// 서비스의 메소드로 검색할 아이디를 전달해서 조회
		// 해당 아이디를 쓰는 회원이 있으면 false, 없으면 true 리턴 받음
		boolean result = memberService.idCheck(searchId);
		
		log.debug("전달된 ID 검색 결과 : {}", result);
		
		// 검색한 아이디와 조회결과를 모델에 저장
		model.addAttribute("searchId", searchId);
		model.addAttribute("result", result);
		
		// 검색 페이지로 다시 이동
		return "memberView/idCheck";
	}
	
}

 

 

(5) 결과 화면

첫 접속 화면

 

 

"회원가입" 문구 클릭 시 화면

- ID 입력란은 직접 입력할 수 없도록 처리해놓음

- "ID 중복확인" 버튼 클릭 시 나오는 ID 중복확인 창(새창)에서 가입 가능여부를 체크함

- 가입 가능 시 출력되는 "ID 사용하기" 버튼을 클릭하여 ID 입력란에 자동으로 값을 넣어줌