- 회원가입 form


왼쪽이 실제 네이버의 회원가입 form이고 오른쪽이 클론코딩으로 만든 회원가입 form
필요한 부분만 사용을했고 필요 없는 부분은 제외
- memberSave.jsp
<section>
<form action="/member/save" method="post" onsubmit="return save_check()">
<div id="save-container">
<div id="save-container-contents">
<div> <!-- 가입폼 전체 -->
<div class="contents-group"><!--이메일 , 비밀번호1,2-->
<div id="group-id"><!--이메일 css 없음-->
<h3 class="join-title">
<label for="memberEmail">아이디</label>
</h3>
<span class="ps_box" style="background: #fff;outline: 0;">
<input type="text" id="memberEmail" name="memberEmail" class="save-input"
maxlength="20" onblur="email_check()">
<span id="Email-domain">@naver.com</span>
</span>
<span class="err-box" id="emailResult"></span>
</div>
<div id="group-pw"><!--비밀번호 1차 2차 css 없음-->
<h3 class="join-title">
<label for="memberPassword">비밀번호</label>
</h3>
<span class="ps_box pswd1Img" id="pswd1Img">
<input type="password" id="memberPassword" name="memberPassword" class="save-input"
onblur="pass_check()">
<span class="lbl">
<span id="pswd1Span" class="step_txt"></span>
</span>
</span>
<span class="err-box" id="passResult"></span>
<h3 class="join-title">
<label for="memberPassword1">비밀번호 재확인</label>
</h3>
<span class="ps_box pswd2Img" id="pswd2Img">
<input type="password" id="memberPassword1" name="memberPassword1" class="save-input" onblur="pass1_check()">
</span>
<span class="err-box" id="passResult1" style="margin: 9px 0 0;"></span>
</div>
</div>
<div class="contents-group"><!--이름 , 생년 , 성별-->
<div id="group-name"><!--이름 css 없음-->
<h3 class="join-title">
<label for="memberName">이름</label>
</h3>
<span class="ps_box box_right_space">
<input type="text" id="memberName" name="memberName" class="save-input" onblur="name_check()">
</span>
<span class="err-box" id="nameResult"></span>
</div>
<div id="group-birthday"> <!--생일 css 없음-->
<h3 class="join-title">
<label for="yy">생년월일</label>
</h3>
<div id="birthday-box">
<div class="bir_yy">
<span class="ps_box" style="padding: 11px 14px;">
<input type="text" id="yy" name="memberBiryy" placeholder="년(4자)" class="save-input"
maxlength="4" onblur="bir_check()">
</span>
</div>
<div class="bir_mm">
<span class="ps_box" style="padding: 11px 14px;">
<select id="mm" name="memberBirmm" class="sel" onblur="bir_check()">
<option value="">월</option>
<option value="01">
1
</option>
<option value="02">
2
</option>
<option value="03">
3
</option>
<option value="04">
4
</option>
<option value="05">
5
</option>
<option value="06">
6
</option>
<option value="07">
7
</option>
<option value="08">
8
</option>
<option value="09">
9
</option>
<option value="10">
10
</option>
<option value="11">
11
</option>
<option value="12">
12
</option>
</select>
</span>
</div>
<div class="bir_dd">
<span class="ps_box" style="padding: 11px 14px;">
<input type="text" id="dd" name="memberBirdd" placeholder="일" class="save-input"
maxlength="2" onblur="bir_check()">
<label for="dd" class="lbl"></label>
</span>
</div>
</div>
<span class="err-box" id="birResult"></span>
</div>
<div id="group-gender"> <!-- 성별 css x -->
<h3 class="join-title">
<label for="memberGender">성별</label>
</h3>
<div class="ps_box gender_code">
<select id="memberGender" name="memberGender" class="sel">
<option value="" selected="">성별</option>
<option value="M">남자</option>
<option value="F">여자</option>
<option value="U">선택 안함</option>
</select>
</div>
</div>
<span class="err-box" id="genderResult" style="margin: 9px 0 0;"></span>
</div>
<div style="margin: 30px 0 9px;">
<button type="submit" id="save-button"><span>가입하기</span></button>
</div>
</div>
</div>
</div>
</form>
엄청 길지만 막상 뜯어보면 css가 절반 이상입니다
특이점은 사용자가에 생년월일을 입력받을 때 input , select , input을 사용했다는 점입니다
년 , 월 , 일 을 따로 입력받고 Controller에서 하나로 합쳐 DB로 넘겨줍니다
- memberSave.jsp - script
<script>
const memberEmail = document.getElementById('memberEmail');
email을 입력받는 input 태그의 객체
const emailResult = document.getElementById('emailResult');
입력받은 email 체크에 따른 Result
const memberPassword = document.getElementById('memberPassword');
password를 입력받는 input 태그 객체
const passResult = document.getElementById('passResult');
입력받은 password 체크에 따른 Result
const memberPassword1 = document.getElementById('memberPassword1');
비밀번호 확인을 입력받는 input 태그의 객체
const passResult1 = document.getElementById('passResult1');
비밀번호 확인 체크에 따른 Result
const memberName = document.getElementById('memberName');
이름을 입력받는 input 태그의 객체
const nameResult = document.getElementById('nameResult');
이름 체크에 따른 Result
const memberBiryy = document.getElementById('yy');
const memberBirmm = document.getElementById('mm');
const memberBirdd = document.getElementById('dd');
생년월일을 입력받는 input , select ,input 태그의 객체
const birResult = document.getElementById('birResult');
생년월일 입력 체크에 따른 Result
const memberGender = document.getElementById('memberGender');
성별을 입력받는 select 태그의 객체
const genderResult = document.getElementById('genderResult');
성별 체크에 따른 Result
const save_check = () => {
최종적인 유효성 체크를 진행하는 함수
하나라도 입력하지 않거나 조건에 맞지 않다면 submit을 진행하지 않음
if (!(email_check())) { email_check 함수의 리턴이 false일때 실행
memberEmail.focus();
return false;
} else if(!(pass_check())){ pass_check 함수의 리턴이 false일때 실행
memberPassword.focus();
return false;
} else if(!(pass1_check())){ pass1_check 함수의 리턴이 false일때 실행
memberPassword1.focus();
return false;
} else if(!(name_check())){ name_check 함수의 리턴이 false일때 실행
memberName.focus();
return false;
} else if(!(bir_check())){ bir_check 함수의 리턴이 false 일때 실행
if(memberBiryy.value.length < 4) {
memberBiryy.focus();
return false;
}else if(memberBirmm.value == ""){
memberBirmm.focus();
return false;
}else if(memberBirdd.value.length < 2) {
memberBirdd.focus();
return false;
}
birth는 입력을 3가지로 나누어 받기 때문에
if문안에 한번 더 if문을 사용하여 어떤 부분을 입력하지 않았는지
체크 후 focus
} else if(!(gender_check())){ gender_check 함수의 리턴이 false 일때 실행
memberGender.focus();
return false;
} else { 위의 if문에 포함하지 않는다면 true를 리턴하며 submit
return true;
}
}
const email_check = () => { eamil 유효성 검사를 진행하는 함수
const exp = /^[a-z0-9_-]{5,20}$/;
소문자,숫자,특문-_이 사용가능 최소길이는 5 최대 20 제한
$.ajax({
email의 경우 유니크로 설정했기 때문에 DB에 해당 email이 있는지 확인이 필요합니다
그렇기 사용자의 편의를 위해 비동기 처리방식인 ajax를 사용합니다
type: "post",
url: "/member/emailcheck",
data: {
"memberEmail": memberEmail.value
},
success: function () {
사용자가 입력한 email이 db에 없는 경우 사용가능하다
if (memberEmail.value.length = 0) {
emailResult.style.color = "red";
emailResult.innerHTML = "필수 정보입니다.";
checkResult = false;
} else if (!(memberEmail.value.match(exp))) {
emailResult.style.color = "red";
emailResult.innerHTML = "5~20자의 영문 소문자, 숫자와 특수기호(_),(-)만 사용 가능합니다.";
checkResult = false;
} else {
emailResult.style.color = "green";
emailResult.innerHTML = "멋진 아이디네요!";
checkResult = true;
}
각 상황에 맞게 return true false를 리턴하고
이 리턴값은 최종적인 유효성 검사에서 사용된다
},
error: function () {
사용자가 입력한 email이 db에 있는 경우 사용 불가능하다
emailResult.style.color = "red";
emailResult.innerHTML = "이미 사용중이거나 탈퇴한 아이디입니다.";
checkResult = false;
}
})
return checkResult;
}
const pass_check = () => {
사용자가 입력한 비밀번호를 체크하는 함수입니다
패스워드는 중복되어도 상관이 없기 때문에 ajax를 사용하지 않았습니다
const exp = /^(?=.*[a-zA-Z])(?=.*\d)(?=.*[@#$%^&+=!])(?!.*\s).{8,16}$/
최소 8자에서 최대 16자까지 사용이 가능하고
하나의 영문 알파벳이 포함 (대소상관x)
하나의 숫자 하나의 특수문자가 포함되어야 한다는 정규식 표현입니다
const pswd1Span = document.getElementById('pswd1Span');
패스워드에서는 input 태그 옆에 한번 더 사용 가능 여부를 알려주기 때문에
추가적인 Result 태그를 사용하였습니다
if (memberPassword.value.length == 0) {
passResult.style.color = "red";
pswd1Span.style.color = "red";
$('#pswd1Img').removeClass('ps_box pswd1Img');
$('#pswd1Img').removeClass('ps_box pswd1Img-2');
$('#pswd1Img').addClass('ps_box pswd1Img-1');
클레스 이름에 따라 스타일을 적용하였기 때문에
제이쿼리를 사용하여 해당 상황에 맞게 클래스의 이름을 변경했습니다
pswd1Span.innerHTML = "사용불가";
passResult.innerHTML = "필수 정보입니다.";
return false;
} else if(!(memberPassword.value.match(exp))) {
passResult.style.color = "red";
pswd1Span.style.color = "red";
$('#pswd1Img').removeClass('ps_box pswd1Img');
$('#pswd1Img').removeClass('ps_box pswd1Img-2');
$('#pswd1Img').addClass('ps_box pswd1Img-1');
클레스 이름에 따라 스타일을 적용하였기 때문에
제이쿼리를 사용하여 해당 상황에 맞게 클래스의 이름을 변경했습니다
pswd1Span.innerHTML = "사용불가";
passResult.innerHTML = "8~16자 영문 대 소문자, 숫자, 특수문자를 사용하세요.";
return false;
} else {
passResult.style.color = "green";
pswd1Span.style.color = "green";
$('#pswd1Img').removeClass('ps_box pswd1Img');
$('#pswd1Img').removeClass('ps_box pswd1Img-1');
$('#pswd1Img').addClass('ps_box pswd1Img-2');
클레스 이름에 따라 스타일을 적용하였기 때문에
제이쿼리를 사용하여 해당 상황에 맞게 클래스의 이름을 변경했습니다
pswd1Span.innerHTML = "안전";
passResult.innerHTML = "";
안전인 경우 input 태그 옆의 Result를 넣어주는 태그는 남겨두고
하단의 Result 태그의 내용을 지웁니다
return true;
}
}
const pass1_check = () => {
비밀번호 확인을 체크하는 함수입니다
이부분에서는 입력받은 비밀번호와 한번 더 작성한 비밀번호가
맞는지 확인하는 부분이기 때문에 따로 설명을하지 않겠습니다
if(memberPassword1.value.length == 0){
$('#pswd2Img').removeClass('ps_box pswd2Img-1');
$('#pswd2Img').addClass('ps_box pswd2Img');
passResult1.style.color = "red";
passResult1.innerHTML = "필수 정보입니다.";
return false;
} else if(memberPassword.value != memberPassword1.value) {
$('#pswd2Img').removeClass('ps_box pswd2Img-1');
$('#pswd2Img').addClass('ps_box pswd2Img');
passResult1.style.color = "red";
passResult1.innerHTML = "비밀번호가 일치하지 않습니다.";
return false;
} else {
$('#pswd2Img').removeClass('ps_box pswd2Img');
$('#pswd2Img').addClass('ps_box pswd2Img-1');
passResult1.innerHTML = "";
return true;
}
}
const name_check = () => {사용자의 이름을 체크하는 함수입니다
이름의 경우 따로 제약조건을 두지 않았습니다
길이가 0이아닐경우 모두 사용 가능합니다
if(memberName.value.length == 0){
nameResult.style.color = "red";
nameResult.innerHTML = "필수 정보입니다.";
return false;
} else {
nameResult.style.color = "green";
nameResult.innerHTML = "";
return true;
}
}
const bir_check = () => { 사용자의 생년월일을 체크하는 함수입니다
사용자가 입력해야하는 값은 총 3가지이고
길이만 맞다면 별다른 제약 조건은 두지 않았습니다
if(memberBiryy.value.length < 4) {
birResult.style.color = "red";
birResult.innerHTML = "태어난 년도 4자리를 정확하게 입력하세요.";
return false;
} else if(memberBirmm.value == ""){
birResult.style.color = "red";
birResult.innerHTML = "태어난 월을 선택하세요.";
return false;
} else if (memberBirdd.value.length < 2){
birResult.style.color = "red";
birResult.innerHTML = "태어난 일(날짜) 2자리를 정확하게 입력하세요.";
return false;
} else {
birResult.style.color = "green";
birResult.innerHTML = "";
return true;
}
}
const gender_check = () => { 사용자의 성별을 체크하는 함수입니다
select를 사용한 선택형이기 때문에 사용자가 선택을 했는지 않했는지만
판단하고 넘어갑니다 기본 defult 벨류는 값이 없기 때문에 선택했다면 true를 리턴합니다
if(memberGender.value == ""){
genderResult.style.color = "red";
genderResult.innerHTML = "필수 정보입니다.";
return false;
} else {
genderResult.style.color = "green";
genderResult.innerHTML = "";
return true;
}
}
</script>
- Controller
Ajax에서 넘겨받은 값을 DB로보내 유효성 체크를 진행하는 Post 맵핑
@PostMapping("/member/emailcheck")
public ResponseEntity emailcheck(@RequestParam("memberEmail") String memberEmail){
ResponseEntity를 사용하여 에러코드를 핸들링 합니다
파라미터로 넘어오는 값을 ReauestParam을 사용하여 받습니다
String dbEmail = memberService.emailcheck(memberEmail);
Servive , Repository , Mapper 를 통하여
DB에 해당 email이 있다면 값을 가져옵니다 쿼리문을 select로 사용하였기 때문에
같은 이메일 정보가 있다면 값을 리턴합니다
if(dbEmail != null) {
return new ResponseEntity(HttpStatus.CONFLICT);
가져온 값이 null이 아니라면 해당 이메일은 DB에 있는 이메일이기 때문에
ok이가 아닌 conflict를 사용하여 err로 넘겨줍니다
} else {
return new ResponseEntity(HttpStatus.OK);
null이라면 해당 email이 DB에 없다는 말이기 때문에
사용가능으로 ok를 리턴합니다
}
}
@PostMapping("/member/save")
public String saveMember(@ModelAttribute MemberDTO memberDTO) {
사용자가 회원가입에 입력한 값을 @ModelAttribute를 사용하여 DTO 객체에 담아줍니다
memberDTO.setMemberBirthday(memberDTO.getMemberBiryy() +"-"+ memberDTO.getMemberBirmm() +"-"+ memberDTO.getMemberBirdd());
사용자의 생년월일의 경우 DB에서는 합쳐서 받고 있기 때문에
Controller에서 하나로 가공하여 DTO에 담습니다
memberDTO.setMemberDomain(memberDTO.getMemberEmail()+"@naver.com");
Domain의 경우에도 입력받은 email 뒤에 @naver.com을 붙여 가공하여 DTO에 담아줍니다
memberService.saveMember(memberDTO);
이렇게 가공이 끝나면 Service 로 memberDTO를 넘겨줍니다
return "/memberPage/memberLogin";
이후 사용자를 로그인 화면으로 돌려보냅니다.
}
- Service / Repository
@Service
public void saveMember(MemberDTO memberDTO) {
memberRepository.saveMember(memberDTO);
}
@Repository
public void saveMember(MemberDTO memberDTO) {
sql.insert("naverMember.saveMember",memberDTO);
}
Controller에서 전달받아 가공된 DTO를 Mapper까지 전달합니다
그외 별다른 기능은 하지 않습니다
- Mapper
<insert id="saveMember" parameterType="member">
insert into member_table(memberEmail, memberDomain,memberPassword,
memberName, memberBirthday, memberGender, memberPoint)
value (#{memberEmail},#{memberDomain},#{memberPassword},
#{memberName},#{memberBirthday},#{memberGender},#{memberPoint})
</insert>
사용자에게 입력받은 값을 쿼리문으로 작성하여 DB에 넣어줍니다



이렇게 잘 저장되어 로그인 페이지로 넘어갔습니다
'나의 수업일지' 카테고리의 다른 글
인천 일보 아카데미 58~67일 차 개인 프로젝트 - NAVER 지식in 클론 코딩 (5) (0) | 2023.06.09 |
---|---|
인천 일보 아카데미 58~67일 차 개인 프로젝트 - NAVER 지식in 클론 코딩 (4) (0) | 2023.06.07 |
인천 일보 아카데미 58~67일 차 개인 프로젝트 - NAVER 지식in 클론 코딩 (2) (0) | 2023.06.07 |
인천 일보 아카데미 58~67일 차 개인 프로젝트 시작 - NAVER 지식in 클론 코딩 (1) (0) | 2023.06.07 |
인천 일보 아카데미 56일~57일차 -회원제 게시판 만들기 - 사진 프리뷰(다중) / 파일 이름 가져오기(다중) / 버튼 - onclick 실행 함수 변경하기 (0) | 2023.05.15 |
- 회원가입 form


왼쪽이 실제 네이버의 회원가입 form이고 오른쪽이 클론코딩으로 만든 회원가입 form
필요한 부분만 사용을했고 필요 없는 부분은 제외
- memberSave.jsp
<section>
<form action="/member/save" method="post" onsubmit="return save_check()">
<div id="save-container">
<div id="save-container-contents">
<div> <!-- 가입폼 전체 -->
<div class="contents-group"><!--이메일 , 비밀번호1,2-->
<div id="group-id"><!--이메일 css 없음-->
<h3 class="join-title">
<label for="memberEmail">아이디</label>
</h3>
<span class="ps_box" style="background: #fff;outline: 0;">
<input type="text" id="memberEmail" name="memberEmail" class="save-input"
maxlength="20" onblur="email_check()">
<span id="Email-domain">@naver.com</span>
</span>
<span class="err-box" id="emailResult"></span>
</div>
<div id="group-pw"><!--비밀번호 1차 2차 css 없음-->
<h3 class="join-title">
<label for="memberPassword">비밀번호</label>
</h3>
<span class="ps_box pswd1Img" id="pswd1Img">
<input type="password" id="memberPassword" name="memberPassword" class="save-input"
onblur="pass_check()">
<span class="lbl">
<span id="pswd1Span" class="step_txt"></span>
</span>
</span>
<span class="err-box" id="passResult"></span>
<h3 class="join-title">
<label for="memberPassword1">비밀번호 재확인</label>
</h3>
<span class="ps_box pswd2Img" id="pswd2Img">
<input type="password" id="memberPassword1" name="memberPassword1" class="save-input" onblur="pass1_check()">
</span>
<span class="err-box" id="passResult1" style="margin: 9px 0 0;"></span>
</div>
</div>
<div class="contents-group"><!--이름 , 생년 , 성별-->
<div id="group-name"><!--이름 css 없음-->
<h3 class="join-title">
<label for="memberName">이름</label>
</h3>
<span class="ps_box box_right_space">
<input type="text" id="memberName" name="memberName" class="save-input" onblur="name_check()">
</span>
<span class="err-box" id="nameResult"></span>
</div>
<div id="group-birthday"> <!--생일 css 없음-->
<h3 class="join-title">
<label for="yy">생년월일</label>
</h3>
<div id="birthday-box">
<div class="bir_yy">
<span class="ps_box" style="padding: 11px 14px;">
<input type="text" id="yy" name="memberBiryy" placeholder="년(4자)" class="save-input"
maxlength="4" onblur="bir_check()">
</span>
</div>
<div class="bir_mm">
<span class="ps_box" style="padding: 11px 14px;">
<select id="mm" name="memberBirmm" class="sel" onblur="bir_check()">
<option value="">월</option>
<option value="01">
1
</option>
<option value="02">
2
</option>
<option value="03">
3
</option>
<option value="04">
4
</option>
<option value="05">
5
</option>
<option value="06">
6
</option>
<option value="07">
7
</option>
<option value="08">
8
</option>
<option value="09">
9
</option>
<option value="10">
10
</option>
<option value="11">
11
</option>
<option value="12">
12
</option>
</select>
</span>
</div>
<div class="bir_dd">
<span class="ps_box" style="padding: 11px 14px;">
<input type="text" id="dd" name="memberBirdd" placeholder="일" class="save-input"
maxlength="2" onblur="bir_check()">
<label for="dd" class="lbl"></label>
</span>
</div>
</div>
<span class="err-box" id="birResult"></span>
</div>
<div id="group-gender"> <!-- 성별 css x -->
<h3 class="join-title">
<label for="memberGender">성별</label>
</h3>
<div class="ps_box gender_code">
<select id="memberGender" name="memberGender" class="sel">
<option value="" selected="">성별</option>
<option value="M">남자</option>
<option value="F">여자</option>
<option value="U">선택 안함</option>
</select>
</div>
</div>
<span class="err-box" id="genderResult" style="margin: 9px 0 0;"></span>
</div>
<div style="margin: 30px 0 9px;">
<button type="submit" id="save-button"><span>가입하기</span></button>
</div>
</div>
</div>
</div>
</form>
엄청 길지만 막상 뜯어보면 css가 절반 이상입니다
특이점은 사용자가에 생년월일을 입력받을 때 input , select , input을 사용했다는 점입니다
년 , 월 , 일 을 따로 입력받고 Controller에서 하나로 합쳐 DB로 넘겨줍니다
- memberSave.jsp - script
<script>
const memberEmail = document.getElementById('memberEmail');
email을 입력받는 input 태그의 객체
const emailResult = document.getElementById('emailResult');
입력받은 email 체크에 따른 Result
const memberPassword = document.getElementById('memberPassword');
password를 입력받는 input 태그 객체
const passResult = document.getElementById('passResult');
입력받은 password 체크에 따른 Result
const memberPassword1 = document.getElementById('memberPassword1');
비밀번호 확인을 입력받는 input 태그의 객체
const passResult1 = document.getElementById('passResult1');
비밀번호 확인 체크에 따른 Result
const memberName = document.getElementById('memberName');
이름을 입력받는 input 태그의 객체
const nameResult = document.getElementById('nameResult');
이름 체크에 따른 Result
const memberBiryy = document.getElementById('yy');
const memberBirmm = document.getElementById('mm');
const memberBirdd = document.getElementById('dd');
생년월일을 입력받는 input , select ,input 태그의 객체
const birResult = document.getElementById('birResult');
생년월일 입력 체크에 따른 Result
const memberGender = document.getElementById('memberGender');
성별을 입력받는 select 태그의 객체
const genderResult = document.getElementById('genderResult');
성별 체크에 따른 Result
const save_check = () => {
최종적인 유효성 체크를 진행하는 함수
하나라도 입력하지 않거나 조건에 맞지 않다면 submit을 진행하지 않음
if (!(email_check())) { email_check 함수의 리턴이 false일때 실행
memberEmail.focus();
return false;
} else if(!(pass_check())){ pass_check 함수의 리턴이 false일때 실행
memberPassword.focus();
return false;
} else if(!(pass1_check())){ pass1_check 함수의 리턴이 false일때 실행
memberPassword1.focus();
return false;
} else if(!(name_check())){ name_check 함수의 리턴이 false일때 실행
memberName.focus();
return false;
} else if(!(bir_check())){ bir_check 함수의 리턴이 false 일때 실행
if(memberBiryy.value.length < 4) {
memberBiryy.focus();
return false;
}else if(memberBirmm.value == ""){
memberBirmm.focus();
return false;
}else if(memberBirdd.value.length < 2) {
memberBirdd.focus();
return false;
}
birth는 입력을 3가지로 나누어 받기 때문에
if문안에 한번 더 if문을 사용하여 어떤 부분을 입력하지 않았는지
체크 후 focus
} else if(!(gender_check())){ gender_check 함수의 리턴이 false 일때 실행
memberGender.focus();
return false;
} else { 위의 if문에 포함하지 않는다면 true를 리턴하며 submit
return true;
}
}
const email_check = () => { eamil 유효성 검사를 진행하는 함수
const exp = /^[a-z0-9_-]{5,20}$/;
소문자,숫자,특문-_이 사용가능 최소길이는 5 최대 20 제한
$.ajax({
email의 경우 유니크로 설정했기 때문에 DB에 해당 email이 있는지 확인이 필요합니다
그렇기 사용자의 편의를 위해 비동기 처리방식인 ajax를 사용합니다
type: "post",
url: "/member/emailcheck",
data: {
"memberEmail": memberEmail.value
},
success: function () {
사용자가 입력한 email이 db에 없는 경우 사용가능하다
if (memberEmail.value.length = 0) {
emailResult.style.color = "red";
emailResult.innerHTML = "필수 정보입니다.";
checkResult = false;
} else if (!(memberEmail.value.match(exp))) {
emailResult.style.color = "red";
emailResult.innerHTML = "5~20자의 영문 소문자, 숫자와 특수기호(_),(-)만 사용 가능합니다.";
checkResult = false;
} else {
emailResult.style.color = "green";
emailResult.innerHTML = "멋진 아이디네요!";
checkResult = true;
}
각 상황에 맞게 return true false를 리턴하고
이 리턴값은 최종적인 유효성 검사에서 사용된다
},
error: function () {
사용자가 입력한 email이 db에 있는 경우 사용 불가능하다
emailResult.style.color = "red";
emailResult.innerHTML = "이미 사용중이거나 탈퇴한 아이디입니다.";
checkResult = false;
}
})
return checkResult;
}
const pass_check = () => {
사용자가 입력한 비밀번호를 체크하는 함수입니다
패스워드는 중복되어도 상관이 없기 때문에 ajax를 사용하지 않았습니다
const exp = /^(?=.*[a-zA-Z])(?=.*\d)(?=.*[@#$%^&+=!])(?!.*\s).{8,16}$/
최소 8자에서 최대 16자까지 사용이 가능하고
하나의 영문 알파벳이 포함 (대소상관x)
하나의 숫자 하나의 특수문자가 포함되어야 한다는 정규식 표현입니다
const pswd1Span = document.getElementById('pswd1Span');
패스워드에서는 input 태그 옆에 한번 더 사용 가능 여부를 알려주기 때문에
추가적인 Result 태그를 사용하였습니다
if (memberPassword.value.length == 0) {
passResult.style.color = "red";
pswd1Span.style.color = "red";
$('#pswd1Img').removeClass('ps_box pswd1Img');
$('#pswd1Img').removeClass('ps_box pswd1Img-2');
$('#pswd1Img').addClass('ps_box pswd1Img-1');
클레스 이름에 따라 스타일을 적용하였기 때문에
제이쿼리를 사용하여 해당 상황에 맞게 클래스의 이름을 변경했습니다
pswd1Span.innerHTML = "사용불가";
passResult.innerHTML = "필수 정보입니다.";
return false;
} else if(!(memberPassword.value.match(exp))) {
passResult.style.color = "red";
pswd1Span.style.color = "red";
$('#pswd1Img').removeClass('ps_box pswd1Img');
$('#pswd1Img').removeClass('ps_box pswd1Img-2');
$('#pswd1Img').addClass('ps_box pswd1Img-1');
클레스 이름에 따라 스타일을 적용하였기 때문에
제이쿼리를 사용하여 해당 상황에 맞게 클래스의 이름을 변경했습니다
pswd1Span.innerHTML = "사용불가";
passResult.innerHTML = "8~16자 영문 대 소문자, 숫자, 특수문자를 사용하세요.";
return false;
} else {
passResult.style.color = "green";
pswd1Span.style.color = "green";
$('#pswd1Img').removeClass('ps_box pswd1Img');
$('#pswd1Img').removeClass('ps_box pswd1Img-1');
$('#pswd1Img').addClass('ps_box pswd1Img-2');
클레스 이름에 따라 스타일을 적용하였기 때문에
제이쿼리를 사용하여 해당 상황에 맞게 클래스의 이름을 변경했습니다
pswd1Span.innerHTML = "안전";
passResult.innerHTML = "";
안전인 경우 input 태그 옆의 Result를 넣어주는 태그는 남겨두고
하단의 Result 태그의 내용을 지웁니다
return true;
}
}
const pass1_check = () => {
비밀번호 확인을 체크하는 함수입니다
이부분에서는 입력받은 비밀번호와 한번 더 작성한 비밀번호가
맞는지 확인하는 부분이기 때문에 따로 설명을하지 않겠습니다
if(memberPassword1.value.length == 0){
$('#pswd2Img').removeClass('ps_box pswd2Img-1');
$('#pswd2Img').addClass('ps_box pswd2Img');
passResult1.style.color = "red";
passResult1.innerHTML = "필수 정보입니다.";
return false;
} else if(memberPassword.value != memberPassword1.value) {
$('#pswd2Img').removeClass('ps_box pswd2Img-1');
$('#pswd2Img').addClass('ps_box pswd2Img');
passResult1.style.color = "red";
passResult1.innerHTML = "비밀번호가 일치하지 않습니다.";
return false;
} else {
$('#pswd2Img').removeClass('ps_box pswd2Img');
$('#pswd2Img').addClass('ps_box pswd2Img-1');
passResult1.innerHTML = "";
return true;
}
}
const name_check = () => {사용자의 이름을 체크하는 함수입니다
이름의 경우 따로 제약조건을 두지 않았습니다
길이가 0이아닐경우 모두 사용 가능합니다
if(memberName.value.length == 0){
nameResult.style.color = "red";
nameResult.innerHTML = "필수 정보입니다.";
return false;
} else {
nameResult.style.color = "green";
nameResult.innerHTML = "";
return true;
}
}
const bir_check = () => { 사용자의 생년월일을 체크하는 함수입니다
사용자가 입력해야하는 값은 총 3가지이고
길이만 맞다면 별다른 제약 조건은 두지 않았습니다
if(memberBiryy.value.length < 4) {
birResult.style.color = "red";
birResult.innerHTML = "태어난 년도 4자리를 정확하게 입력하세요.";
return false;
} else if(memberBirmm.value == ""){
birResult.style.color = "red";
birResult.innerHTML = "태어난 월을 선택하세요.";
return false;
} else if (memberBirdd.value.length < 2){
birResult.style.color = "red";
birResult.innerHTML = "태어난 일(날짜) 2자리를 정확하게 입력하세요.";
return false;
} else {
birResult.style.color = "green";
birResult.innerHTML = "";
return true;
}
}
const gender_check = () => { 사용자의 성별을 체크하는 함수입니다
select를 사용한 선택형이기 때문에 사용자가 선택을 했는지 않했는지만
판단하고 넘어갑니다 기본 defult 벨류는 값이 없기 때문에 선택했다면 true를 리턴합니다
if(memberGender.value == ""){
genderResult.style.color = "red";
genderResult.innerHTML = "필수 정보입니다.";
return false;
} else {
genderResult.style.color = "green";
genderResult.innerHTML = "";
return true;
}
}
</script>
- Controller
Ajax에서 넘겨받은 값을 DB로보내 유효성 체크를 진행하는 Post 맵핑
@PostMapping("/member/emailcheck")
public ResponseEntity emailcheck(@RequestParam("memberEmail") String memberEmail){
ResponseEntity를 사용하여 에러코드를 핸들링 합니다
파라미터로 넘어오는 값을 ReauestParam을 사용하여 받습니다
String dbEmail = memberService.emailcheck(memberEmail);
Servive , Repository , Mapper 를 통하여
DB에 해당 email이 있다면 값을 가져옵니다 쿼리문을 select로 사용하였기 때문에
같은 이메일 정보가 있다면 값을 리턴합니다
if(dbEmail != null) {
return new ResponseEntity(HttpStatus.CONFLICT);
가져온 값이 null이 아니라면 해당 이메일은 DB에 있는 이메일이기 때문에
ok이가 아닌 conflict를 사용하여 err로 넘겨줍니다
} else {
return new ResponseEntity(HttpStatus.OK);
null이라면 해당 email이 DB에 없다는 말이기 때문에
사용가능으로 ok를 리턴합니다
}
}
@PostMapping("/member/save")
public String saveMember(@ModelAttribute MemberDTO memberDTO) {
사용자가 회원가입에 입력한 값을 @ModelAttribute를 사용하여 DTO 객체에 담아줍니다
memberDTO.setMemberBirthday(memberDTO.getMemberBiryy() +"-"+ memberDTO.getMemberBirmm() +"-"+ memberDTO.getMemberBirdd());
사용자의 생년월일의 경우 DB에서는 합쳐서 받고 있기 때문에
Controller에서 하나로 가공하여 DTO에 담습니다
memberDTO.setMemberDomain(memberDTO.getMemberEmail()+"@naver.com");
Domain의 경우에도 입력받은 email 뒤에 @naver.com을 붙여 가공하여 DTO에 담아줍니다
memberService.saveMember(memberDTO);
이렇게 가공이 끝나면 Service 로 memberDTO를 넘겨줍니다
return "/memberPage/memberLogin";
이후 사용자를 로그인 화면으로 돌려보냅니다.
}
- Service / Repository
@Service
public void saveMember(MemberDTO memberDTO) {
memberRepository.saveMember(memberDTO);
}
@Repository
public void saveMember(MemberDTO memberDTO) {
sql.insert("naverMember.saveMember",memberDTO);
}
Controller에서 전달받아 가공된 DTO를 Mapper까지 전달합니다
그외 별다른 기능은 하지 않습니다
- Mapper
<insert id="saveMember" parameterType="member">
insert into member_table(memberEmail, memberDomain,memberPassword,
memberName, memberBirthday, memberGender, memberPoint)
value (#{memberEmail},#{memberDomain},#{memberPassword},
#{memberName},#{memberBirthday},#{memberGender},#{memberPoint})
</insert>
사용자에게 입력받은 값을 쿼리문으로 작성하여 DB에 넣어줍니다



이렇게 잘 저장되어 로그인 페이지로 넘어갔습니다
'나의 수업일지' 카테고리의 다른 글
인천 일보 아카데미 58~67일 차 개인 프로젝트 - NAVER 지식in 클론 코딩 (5) (0) | 2023.06.09 |
---|---|
인천 일보 아카데미 58~67일 차 개인 프로젝트 - NAVER 지식in 클론 코딩 (4) (0) | 2023.06.07 |
인천 일보 아카데미 58~67일 차 개인 프로젝트 - NAVER 지식in 클론 코딩 (2) (0) | 2023.06.07 |
인천 일보 아카데미 58~67일 차 개인 프로젝트 시작 - NAVER 지식in 클론 코딩 (1) (0) | 2023.06.07 |
인천 일보 아카데미 56일~57일차 -회원제 게시판 만들기 - 사진 프리뷰(다중) / 파일 이름 가져오기(다중) / 버튼 - onclick 실행 함수 변경하기 (0) | 2023.05.15 |