수업 정리 bbs-basic/#2(회원가입 중복,사용가능,올바른 입력 처리)

최동민·2022년 6월 14일
0

Spring 수업정리

목록 보기
21/47

회원가입 처리

user/register.html에서 html 작성

<style>
    main > form > label {
        display: block;
    }

    main > form > h2 {
        margin-bottom: 1rem !important;
        margin-block: unset;
        margin-inline: unset;
        padding-inline: unset;
    }

    main > form > label > textarea {
        resize: none;
    }

    main > form > label > input[type=checkbox] + span {
        user-select: none;
    }
</style>

<form id="register-form" method="post">
    <h2>회원가입</h2>
    <label>
        <span>이메일</span>
        <input autofocus maxlength="50" name="email" placeholder="이메일" type="email">
        <span rel="warning"><!--올바른 이메일을 입력해주세요.--></span>
    </label>
    <label>
        <span>비밀번호</span>
        <input maxlength="100" name="password" placeholder="비밀번호" type="password">
        <span rel="warning"><!--올바른 비밀번호 입력해주세요.--></span>
    </label>
    <label>
        <span>비밀번호 확인</span>
        <input maxlength="100" name="passwordCheck" placeholder="비밀번호" type="password">
        <span rel="warning"></span>
    </label>
    <label>
        <span>닉네임</span>
        <input maxlength="10" name="nickname" placeholder="닉네임" type="text">
        <span rel="warning"><!--올바른 닉네임을 입력해주세요.--></span>
    </label>
    <label>
        <span>이용약관</span>
        <textarea readonly>이용약관!이용약관!이용약관!이용약관!이용약관!</textarea>
    </label>
    <label>
        <input name="agree" type="checkbox">
        <span>위 약관을 읽어보았으며 동의합니다.</span>
    </label>
    <input type="reset" value="다시 입력">  <!--누르면 reset된다.-->
    <input type="submit" value="회원 가입">
</form>

js도 추가

<script>
    const registerForm = window.document.getElementById('register-form'); // form태그 id
    const emailRegex = new RegExp('^(?=.{10,100}$)([0-9a-z][0-9a-z_]*[0-9a-z])@([0-9a-z][0-9a-z\\-]*[0-9a-z]\\.)?([0-9a-z][0-9a-z\\-]*[0-9a-z])\\.([a-z]{2,15})(\\.[a-z]{2})?$'); // 이메일 정규식
    const passwordRegex = new RegExp('^([0-9a-zA-Z`~!@#$%^&*()\\-_=+\\[{\\]}\\\\|;:\'",<.>/?]{8,100})$'); // 비밀번호 정규식
    const nicknameRegex = new RegExp('^([0-9a-zA-Z가-힣]{2,10})$'); // 닉네임 정규식
    const emailInput = registerForm['email']; // input name=email
    const emailWarning = registerForm.querySelector('input[name=email] + [rel=warning]'); // 올바르게 입력하세요 의미
    const passwordInput = registerForm['password'];
    const passwordWarning = registerForm.querySelector('input[name=password] + [rel=warning]');
    const passwordCheckInput = registerForm['passwordCheck']; // 한번 더 다시 확인
    const passwordCheckWarning = registerForm.querySelector('input[name=passwordCheck] + [rel=warning]');
    const nicknameInput = registerForm['nickname'];
    const nicknameWarning = registerForm.querySelector('input[name=nickname] + [rel=warning]');
    emailInput.addEventListener('focusout', () => {
        // focusout : 요소가 포커스 잃을 때 이벤트 발생
       emailWarning.style.display = 'none';
       if (!emailRegex.test(emailInput.value)) {
           // test 메소드를 호출하면 emailInput.value의 값이 들어갈 것이고, 위에 적어놓은 정규식을 거쳐서 테스트가 되는지
           // 확인을 하는 함수이다.
           emailWarning.innerText = '올바른 이메일을 입력하세요.';
           emailWarning.style.display = 'inline';
           // inline : 컨텐츠만큼 영역이 잡힌다.
       } else {  // 이메일 입력값이 정규식을 통과했다는 것.
           const xhr = new XMLHttpRequest();
           // /user/register
           // /user/check.email 상대주소 -> 체크 이메일의 주소
           const formDate = new FormData();
           formDate.append('email',emailInput.value);
           xhr.open('POST', 'check-email');
           xhr.onreadystatechange = () => {
               if (xhr.readyState === XMLHttpRequest.DONE) {
                   if (xhr.status >= 200 && xhr.status <300) {
                       const response = parseInt(xhr.responseText) // 전달받은 문자열 값을 숫자로 변환
                       switch (response) {
                           case 0:
                               emailWarning.innerText = '사용 가능한 이메일입니다.';
                               emailWarning.style.display = 'inline';
                               break;
                           case 1:
                               emailWarning.innerText = '해당 이메일은 이미 사용 중입니다.';
                               emailWarning.style.display = 'inline';
                               break;
                           default:
                                emailWarning.innerText = '올바른 이메일을 입력해주세요.';
                                emailWarning.style.display = 'inline';
                                break;
                       }
                   }
               }
           };
           xhr.send(formDate);
       }
    });

    passwordInput.addEventListener('focusout', () => {
        passwordWarning.style.display = 'none';
        if (!passwordRegex.test(passwordInput.value)) {
            passwordWarning.innerText = '올바른 비밀번호를 입력하세요.';
            passwordWarning.style.display = 'inline';
        }
    });

    passwordCheckInput.addEventListener('focusout', () => {
        passwordCheckWarning.style.display = 'none';
        if (passwordCheckInput.value !== passwordInput.value) {
            passwordCheckWarning.innerText = '비밀번호가 일치하지 않습니다.';
            passwordCheckWarning.style.display = 'inline';

        }
    });

    nicknameInput.addEventListener('focusout', () => {
        nicknameWarning.style.display = 'none';
        if (!nicknameRegex.test(nicknameInput.value)) {
            nicknameWarning.innerText = '올바른 닉네임을 입력하세요.';
            nicknameWarning.style.display = 'inline';
        } else {
            const xhr = new XMLHttpRequest();
            const formDate = new FormData();
            formDate.append('nickname', nicknameInput.value);
            xhr.open('POST', 'check-nickname');
            xhr.onreadystatechange = () => {
                if (xhr.readyState === XMLHttpRequest.DONE) {
                    if (xhr.status >= 200 && xhr.status < 300) {
                        const response = parseInt(xhr.responseText)
                        switch (response) {
                            case 0:
                                nicknameWarning.innerText = '사용 가능한 닉네임입니다.';
                                nicknameWarning.style.display = 'inline';
                                break;
                            case 1:
                                nicknameWarning.innerText = '해당 닉네임은 이미 사용 중입니다.';
                                nicknameWarning.style.display = 'inline';
                                break;
                            default:
                                nicknameWarning.innerText = '올바른 닉네임을 입력해주세요.';
                                nicknameWarning.style.display = 'inline';
                                break;
                        }
                    }
                }
            };
            xhr.send(formDate);
        }
    });

    registerForm.onsubmit = e => {
        emailWarning.style.display = 'none';
        passwordWarning.style.display = 'none';
        passwordCheckWarning.display = 'none';
        nicknameWarning.dispaly = 'none';
        if(!emailRegex.test(emailInput.value)) { // 받아온 값이 정규식과 맞지 않다면
            emailWarning.innerText = '올바른 이메일을 입력해주세요.';
            emailWarning.style.display ='inline';
            emailWarning.focus(); // 박스에 포커스 두어짐
            emailWarning.select(); // 텍스트 선택됨
            e.preventDefault();
            return false;
        }
        if(!passwordRegex.test(passwordInput.value)) {
            passwordWarning.innerText ='올바른 비밀번호를 입력해주세요.';
            passwordWarning.style.display = 'inline';
            passwordInput.focus();
            passwordInput.select();
            e.preventDefault();
            return false;
        }
        if(passwordInput.value !== passwordCheckInput.value) {
            passwordCheckWarning.innerText = '비밀번호가 일치하지 않습니다.';
            passwordCheckWarning.style.display = 'inline';
            passwordCheckInput.focus();
            passwordCheckInput.select();
            e.preventDefault();
            return false;
        }

        if(!nicknameRegex.test(nicknameInput.value)) {
            nicknameWarning.innerText ='올바른 닉네임을 입력해주세요.';
            nicknameWarning.style.display = 'inline';
            nicknameInput.focus();
            nicknameInput.select();
            e.preventDefault();
            return false;
        }
        if(!registerForm['agree'].checked) { // 체크박스가 체크되어있지 않으면
            alert('이용약관을 읽고 동의해주세요.');
            registerForm['agree'].focus();
            registerForm['agree'].select();
            e.preventDefault();
            return false;
        }
    };

</script>

focusout이 발생했을 때 정규식과 입력한 값이 맞지 않으면
올바른 입력을 요구하도록 설정.
submit이 발생했을 때 모든 warning에 대한 디스플레이를 none으로 설정.
email과 nickname이 사용 중인지, 사용 가능한지에 대해 서버와 통신하여 알아볼 것.

우선 uesrs 테이블에 레코드 추가

entities 패키지 만들고 UserEntity 생성

package dev.dmchoi.bbsbasic.entities;

public class UserEntity {
    private int index;
    private String email;
    private String password;
    private String nickname;
    private boolean isDeleted;
    private boolean isSuspended;
    private boolean isAdmin;


    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    public int getIndex() {
        return index;
    }

    public void setIndex(int index) {
        this.index = index;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public boolean isDeleted() {
        return isDeleted;
    }

    public void setDeleted(boolean deleted) {
        isDeleted = deleted;
    }

    public boolean isSuspended() {
        return isSuspended;
    }

    public void setSuspended(boolean suspended) {
        isSuspended = suspended;
    }

    public boolean isAdmin() {
        return isAdmin;
    }

    public void setAdmin(boolean admin) {
        isAdmin = admin;
    }
}

Mappers 패키지에서 IUserMapper 생성

이메일과 패스워드 메소드 추가

services 패키지의 UserService 에서
matches로 정규식과 동일한 내용인지를 체크

UserMapper.xml 만들고 IUserMapper의 메소드 두개와 그 파라미터를 연결.
#{}은 파스칼케이싱을 한 다음 앞에 get을 붙여서 이 메소드가 있다면 땡겨온다. 결과적으로 UserEntity의 getEmail을 가져온다.

UserController에서 추가

포스트맨으로 체크해보자
http://localhost:8080/user/check-email

DB에 있는 이메일 입력 시 1,
없는 이메일 입력 시 0,
정규식 틀리게 입력 시 -1 나온다.

profile
코드를 두드리면 문이 열린다

0개의 댓글