Spring - 회원가입

맑은 눈의 코드 👀·2023년 8월 14일
0

06_framework 이론

목록 보기
6/23
post-thumbnail

🧁 게시판에 회원가입 구현하기

이메일 인증번호/ 주소 관련

🧃 signUp.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>


<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>회원가입</title>


    <link rel="stylesheet" href="/resources/css/member/signUp-style.css">
</head>
<body>
    <main>
        <%-- header.jsp include --%>
        <%-- 다른 jsp 코드를 현재 위치에 포함 webapp부터의 jsp경로를 작성 --%>
        <jsp:include page="/WEB-INF/views/common/header.jsp"/>
       


        <section class="signUp-content">


            <form action="/member/signUp" method="POST" name="signUpFrm" id="signUpFrm">


                <!-- 이메일 입력 -->
                <label for="memberEmail">
                    <span class="required">*</span> 아이디(이메일)
                </label>


                <div class="signUp-input-area">
                    <input type="text" name="memberEmail" id="memberEmail"
                    placeholder="아이디(이메일)" maxlength="30" autocomplete="off">
                   
                    <button id="sendAuthKeyBtn" type="button">인증번호 받기</button>
                </div>
                <span class="signUp-message" id="emailMessage">메일을 받을 수 있는 이메일을 입력해주세요.</span>






                <!-- 인증번호 입력 -->
                <label for="emailCheck">
                    <span class="required">*</span> 인증번호
                </label>


                <div class="signUp-input-area">
                    <input type="text" name="authKey" id="authKey" s placeholder="인증번호 입력" maxlength="6" autocomplete="off" >
                   
                    <button id="checkAuthKeyBtn" type="button">인증하기</button>
                </div>
                <span class="signUp-message" id="authKeyMessage"></span>
                                <!-- 인증번호가 일치하지 않습니다 -->
               


                <!-- 비밀번호/비밀번호 확인 입력 -->
                <label for="memberPw">
                    <span class="required">*</span> 비밀번호
                </label>


                <div class="signUp-input-area">
                    <input type="password" name="memberPw" id="memberPw"
                    placeholder="비밀번호" maxlength="20" >
                </div>
                <div class="signUp-input-area">
                    <input type="password" name="memberPwConfirm" id="memberPwConfirm"
                    placeholder="비밀번호 확인" maxlength="20" >
                </div>


                <span class="signUp-message" id="pwMessage">영어,숫자,특수문자(!,@,#,-,_) 6~20글자 사이로 입력해주세요.</span>




                <!-- 닉네임 입력 -->
                <label for="memberNickname">
                    <span class="required">*</span> 닉네임
                </label>


                <div class="signUp-input-area">
                    <input type="text" name="memberNickname" id="memberNickname" placeholder="닉네임" maxlength="10" >
                </div>


                <span class="signUp-message" id="nickMessage">한글,영어,숫자로만 2~10글자</span>




                <!-- 전화번호 입력 -->
                <label for="memberTel">
                    <span class="required">*</span> 전화번호
                </label>


                <div class="signUp-input-area">
                    <input type="text" name="memberTel" id="memberTel" placeholder="(- 없이 숫자만 입력)" maxlength="11">
                </div>


                <span class="signUp-message" id="telMessage">전화번호를 입력해주세요.(- 제외)</span>






                <!-- 주소 입력 -->
                <label for="memberAddress">주소</label>


                <div class="signUp-input-area">
                    <input type="text" name="memberAddress" placeholder="우편번호" maxlength="6" id="sample6_postcode">
                   
                    <button type="button" onclick="sample6_execDaumPostcode()">검색</button>
                </div>


                <div class="signUp-input-area">
                    <input type="text" name="memberAddress" placeholder="도로명/지번 주소" id="sample6_address">
                </div>


                <div class="signUp-input-area">
                    <input type="text" name="memberAddress" placeholder="상세 주소" id="sample6_detailAddress">
                </div>




                <button id="signUpBtn">가입하기</button>
            </form>
        </section>


    </main>


    <%-- footer.jsp include --%>
    <jsp:include page="/WEB-INF/views/common/footer.jsp"/>
    <script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
    <script>
        function sample6_execDaumPostcode() {
            new daum.Postcode({
                oncomplete: function(data) {
                    // 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분.

                    // 각 주소의 노출 규칙에 따라 주소를 조합한다.
                    // 내려오는 변수가 값이 없는 경우엔 공백('')값을 가지므로, 이를 참고하여 분기 한다.
                    var addr = ''; // 주소 변수
                   

                    //사용자가 선택한 주소 타입에 따라 해당 주소 값을 가져온다.
                    if (data.userSelectedType === 'R') { // 사용자가 도로명 주소를 선택했을 경우
                        addr = data.roadAddress;
                    } else { // 사용자가 지번 주소를 선택했을 경우(J)
                        addr = data.jibunAddress;
                    }

                    

                    // 우편번호와 주소 정보를 해당 필드에 넣는다.
                    document.getElementById('sample6_postcode').value = data.zonecode;
                    document.getElementById("sample6_address").value = addr;
                    // 커서를 상세주소 필드로 이동한다.
                    document.getElementById("sample6_detailAddress").focus();
                }
            }).open();
        }
    </script>
</body>
</html>

🧃memberController

//회원가입 페이지 이동
	@GetMapping("/signUp")
	public String signUp() {
		
		// /WEB-INF/views/member/signUp.jsp forward(요청위임)
		// -> ViewResovler 가 prㄷfix , suffix 를 리턴 값 앞 뒤에 붙임
		return "member/signUp";
	}
	
	//회원가입 진행
	@PostMapping("/signUp")
	public String signUp(Member inputMember
						, String[] memberAddress
						, RedirectAttributes ra) {
		
		//---------------메게 변수 설명---------------------------------
		// Member inputMember : 커맨드 객체(제출된 파라미터가 저장된 객체)
	
		// String[] memberAddress :
		// input name ="memberAddress" 3개가 저장된 배열
		
		// RedirectAttuributes ra :
		// 리다이렉트 시 데이터를 requestScope로 전달해주는 객체
		
		//-----------------------------------------------------------
		
		
		// 12345^^^서울시^^^2층
		// 주소 구분자 , -> ^^^ 변경
		
		//String addr = inputMember.getMemberAddress().replace(",", "^^^");
		//inputMember.setMemberAddress(addr);
		//-> 클라이언트가 , 직접 입력하면 문제 발생
		
		
		//만약에 주소를 입력하지 않은 경우 (,,) null로 변경
		if(inputMember.getMemberAddress().equals(",,")) {
			inputMember.setMemberAddress(null);
			
		}else {
			
			// String.join("구분자", String[])
			// 배열의 요소를 하나의 문자열로 변경 
			// 단, 요소 사이에 "구분자" 추가
			String addr = String.join("^^^", memberAddress);
			inputMember.setMemberAddress(addr);
		}
		
		// 회원가입 서비스 호출
		int result = service.signUp(inputMember);
		
		// 가입성공 여부에 따라 주소 결정
		String path ="redirect:";
		String message = null;

		if(result > 0) { //가입성공
			path += "/"; // 메인페이지
			message = inputMember.getMemberNickname()+"님 가입을 축하합니다.";
		
		}else {
			//회원가입 페이지
			path +="/signUp"; //상대경로
			message = "회워가입이 실패했습니다.";
		}
		
		// 리다이렉트 시 session에 잠깐 올라갔다가 내려오도록 세팅
		ra.addFlashAttribute("message", message);
		
		return path;
	}

🧃MemberService 인터페이스

/** 회원 가입 서비스 (비밀번호 암호화)
	 * @param inputMember
	 * @return result(성공 1/ 실패0)
	 */
	int signUp(Member inputMember);

🧃MemberServiceImpl 클래스

//@Transactional(rollbackFor = {Exception.class})
	// 예외가 발생하면 rollback 
	// 발생 안하면 Service 종료시 commit
	//AOP 서비스에서 controller로 넘어가는 시점에서 자동으로 트렌젝션 처리 AOP
	
	// 회원가입서비스
	@Transactional(rollbackFor = {Exception.class})
	@Override
	public int signUp(Member inputMember) {
		
		// 비밀번호를 BCrypt를 이용하여 암호화 후 다시 inputMember에 세팅 
		String encPw = bcrypt.encode(inputMember.getMemberPw());
		inputMember.setMemberPw(encPw);
		
		// DAO 호출
		int result = dao.signUp(inputMember);
		
		return result;
	}

🧃MemberDAO 클래스

/** 회원가입 DAO
	 * @param inputMember
	 * @return result
	 */
	public int signUp(Member inputMember) {
		// 1) mapper의 namespace 지정 후 
		// 	  그 안에 어떤 id를 가지는 sql를 수행할 지 작성
		
		// 2) SQL에 사용할 데이터를 전달 (자료형 중요!)
		
		// return sqlSession.insert("1)namespace.id",2) inputmember);
		
		// inser 성공한 행의 개수 반환
		return sqlSession.insert("memberMapper.signUp",inputMember);
	}

🧃member-mapper.xml

<!-- ***
		insert, update, delete 와 같은 DML구문은 
		수행 결과가 항상 성공한 행의 개수(int 자료형)으로 고정
		-> resultType을 작성하지 않는다 
	 -->
	
	
	<!-- 회원가입 -->	<!-- mybatis-config.xml에 지정된 별칭 -->
	<insert id="signUp" parameterType="Member">
		INSERT INTO "MEMBER"
		VALUES(SEQ_MEMBER_NO.NEXTVAL
			 , #{memberEmail}
			 , #{memberPw}
			 , #{memberNickname}
			 , #{memberTel}
			 , #{memberAddress}
			 , NULL, DEFAULT, DEFAULT, DEFAULT)
	</insert>
profile
나를 죽이지 못하는 오류는 내 코드를 더 강하게 만들지ㅋ

0개의 댓글