회원가입 처리
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 나온다.