21.03.10 Untact프로젝트(관리자 회원가입시 아이디 중복체크 자동화)
2021. 3. 10. 19:40ㆍJAVA/Spring & Vue APP 프로젝트(백엔드)
# NOTE
//실시간으로 아이디 중복체크하는 함수
$(function(){
//.inputLoginId에 뭔가 변화가 있을때(change) 중복체크 실시
$('.inputLoginId').change(function(){
JoinForm__checkLoginIdDup();
});
//.inputLoginId에 키가 입력될 때마다(keyup) 중복체크 실시
//lodash 적용: _.debounce(JoinForm__checkLoginIdDup, 1000)
//키 입력 종료 후 1초 후에 중복체크 함수 실시
$('.inputLoginId').keyup(_.debounce(JoinForm__checkLoginIdDup, 1000));
});
# 주요 소스코드
<join.jsp>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="../part/head.jspf"%>
<!-- lodash 불러오기 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
<script>
const JoinForm__checkAndSubmitDone = false;
let JoinForm__validLoginId = '';
//ajax로 아이디 중복 체크
function JoinForm__checkLoginIdDup(){
const form = $('.formLogin').get(0);
const loginId = form.loginId.value;
form.loginId.value = form.loginId.value.trim();
if (form.loginId.value.length == 0) {
return;
}
$.get(
'getLoginIdDup',
{
loginId
},
function(data){
//기본적으로 초록색
let colorClass = 'text-green-500';
//실패했으면 빨간색
if(data.fail){
colorClass = 'text-red-500';
}
$('.loginIdInputMsg').html("<span class='" + colorClass + "'>" + data.msg + "</span>");
if ( data.fail ) {
form.loginId.focus();
}
else {
JoinForm__validLoginId = data.body.loginId;
form.loginPw.focus();
}
},
'json'
);
};
function JoinForm__checkAndSubmit(form) {
if (JoinForm__checkAndSubmitDone) {
return;
}
form.loginId.value = form.loginId.value.trim();
if (form.loginId.value.length == 0) {
alert('아이디를 입력해주세요.');
form.loginId.focus();
return;
}
if ( form.loginId.value != JoinForm__validLoginId ) {
alert('아이디 중복체크를 해주세요.');
form.loginId.focus();
return;
}
form.loginPw.value = form.loginPw.value.trim();
if (form.loginPw.value.length == 0) {
alert('비밀번호를 입력해주세요.');
form.loginPw.focus();
return;
}
if (form.loginPwConfirm.value.length == 0) {
alert('비밀번호를 확인해 주세요.');
form.loginPwConfirm.focus();
return;
}
if (form.loginPw.value != form.loginPwConfirm.value ) {
alert('비밀번호가 일치하지 않습니다.');
form.loginPwConfirm.focus();
return;
}
form.name.value = form.name.value.trim();
if (form.name.value.length == 0) {
alert('이름을 입력해주세요.');
form.name.focus();
return;
}
form.nickname.value = form.nickname.value.trim();
if (form.nickname.value.length == 0) {
alert('닉네임을 입력해주세요.');
form.nickname.focus();
return;
}
form.email.value = form.email.value.trim();
if (form.email.value.length == 0) {
alert('이메일을 입력해주세요.');
form.email.focus();
return;
}
form.cellphoneNo.value = form.cellphoneNo.value.trim();
if (form.cellphoneNo.value.length == 0) {
alert('전화번호를 입력해주세요.');
form.cellphoneNo.focus();
return;
}
form.submit();
JoinForm__checkAndSubmitDone = true;
}
//실시간으로 아이디 중복체크하는 함수
$(function(){
//.inputLoginId에 뭔가 변화가 있을때(change) 중복체크 실시
$('.inputLoginId').change(function(){
JoinForm__checkLoginIdDup();
});
//.inputLoginId에 키가 입력될 때마다(keyup) 중복체크 실시
//lodash 적용: _.debounce(JoinForm__checkLoginIdDup, 1000)
//키 입력 종료 후 1초 후에 중복체크 함수 실시
$('.inputLoginId').keyup(_.debounce(JoinForm__checkLoginIdDup, 1000));
});
</script>
<section class="section-login">
<div
class="container mx-auto min-h-screen flex items-center justify-center">
<div class="w-full">
<div class="logo-bar flex justify-center mt-3">
<a href="#" class="logo">
<span>
<i class="fas fa-people-arrows"></i>
</span>
<span>UNTACT ADMIN</span>
</a>
</div>
<form class="formLogin bg-white shadow-md rounded px-8 pt-6 pb-8 mt-4"
action="doJoin" method="POST"
onsubmit="JoinForm__checkAndSubmit(this); return false;">
<input type="hidden" name="redirectUrl" value="${param.redirectUrl}" />
<div class="flex flex-col mb-4 md:flex-row">
<div class="p-1 md:w-36 md:flex md:items-center">
<span>아이디</span>
</div>
<div class="p-1 md:flex-grow">
<input
class="inputLoginId shadow appearance-none border rounded w-full py-2 px-3 text-grey-darker"
autofocus="autofocus" type="text" placeholder="아이디를 입력해주세요."
name="loginId" maxlength="20" />
<div class="loginIdInputMsg"></div>
</div>
</div>
<div class="flex flex-col mb-4 md:flex-row">
<div class="p-1 md:w-36 md:flex md:items-center">
<span>비밀번호</span>
</div>
<div class="p-1 md:flex-grow">
<input
class="shadow appearance-none border border-red rounded w-full py-2 px-3 text-grey-darker"
autofocus="autofocus" type="password"
placeholder="비밀번호를 입력해주세요." name="loginPw" maxlength="20" />
</div>
</div>
<div class="flex flex-col mb-4 md:flex-row">
<div class="p-1 md:w-36 md:flex md:items-center">
<span>비밀번호 확인</span>
</div>
<div class="p-1 md:flex-grow">
<input
class="shadow appearance-none border border-red rounded w-full py-2 px-3 text-grey-darker"
autofocus="autofocus" type="password"
placeholder="비밀번호를 확인해주세요." name="loginPwConfirm" maxlength="20" />
</div>
</div>
<div class="flex flex-col mb-4 md:flex-row">
<div class="p-1 md:w-36 md:flex md:items-center">
<span>이름</span>
</div>
<div class="p-1 md:flex-grow">
<input
class="shadow appearance-none border rounded w-full py-2 px-3 text-grey-darker"
autofocus="autofocus" type="text" placeholder="이름을 입력해주세요."
name="name" maxlength="20" />
</div>
</div>
<div class="flex flex-col mb-4 md:flex-row">
<div class="p-1 md:w-36 md:flex md:items-center">
<span>닉네임</span>
</div>
<div class="p-1 md:flex-grow">
<input
class="shadow appearance-none border rounded w-full py-2 px-3 text-grey-darker"
autofocus="autofocus" type="text" placeholder="닉네임을 입력해주세요."
name="nickname" maxlength="20" />
</div>
</div>
<div class="flex flex-col mb-4 md:flex-row">
<div class="p-1 md:w-36 md:flex md:items-center">
<span>이메일</span>
</div>
<div class="p-1 md:flex-grow">
<input
class="shadow appearance-none border rounded w-full py-2 px-3 text-grey-darker"
autofocus="autofocus" type="email" placeholder="이메일을 입력해주세요."
name="email" maxlength="100" />
</div>
</div>
<div class="flex flex-col mb-4 md:flex-row">
<div class="p-1 md:w-36 md:flex md:items-center">
<span>전화번호</span>
</div>
<div class="p-1 md:flex-grow">
<input
class="shadow appearance-none border rounded w-full py-2 px-3 text-grey-darker"
autofocus="autofocus" type="tel" placeholder="전화번호를 입력해주세요.(- 없이 입력해주세요.)"
name="cellphoneNo" maxlength="11" />
</div>
</div>
<div class="flex flex-col mb-4 md:flex-row">
<div class="p-1 md:w-36 md:flex md:items-center">
<span>회원가입</span>
</div>
<div class="p-1">
<input
class="btn-primary bg-blue-500 hover:bg-blue-dark text-white font-bold py-2 px-4 rounded"
type="submit" value="회원가입" />
<a onclick="history.back();" class="btn-info bg-green-500 hover:bg-blue-dark text-white font-bold py-2 px-4 rounded inline-block">뒤로가기</a>
</div>
</div>
</form>
</div>
</div>
</section>
<%@ include file="../part/foot.jspf"%>
<AdmMemberController.java>
@GetMapping("/adm/member/getLoginIdDup")
@ResponseBody
public ResultData getLoginIdDup(String loginId) {
if (loginId == null) {
return new ResultData("F-5", "loginId를 입력해주세요.");
}
if (Util.allNumberString(loginId)) {
return new ResultData("F-3", "로그인아이디는 숫자만으로 구성될 수 없습니다.");
}
if (Util.startsWithNumberString(loginId)) {
return new ResultData("F-4", "로그인아이디는 숫자로 시작할 수 없습니다.");
}
if (loginId.length() < 5) {
return new ResultData("F-5", "로그인아이디는 5자 이상으로 입력해주세요.");
}
if (loginId.length() > 20) {
return new ResultData("F-6", "로그인아이디는 20자 이하로 입력해주세요.");
}
if (Util.isStandardLoginIdString(loginId) == false) {
return new ResultData("F-1", "로그인아이디는 영문소문자와 숫자의 조합으로 구성되어야 합니다.");
}
Member existingMember = memberService.getMemberByLoginId(loginId);
if (existingMember != null) {
return new ResultData("F-2", String.format("%s(은)는 이미 사용중인 로그인아이디 입니다.", loginId));
}
return new ResultData("S-1", String.format("%s(은)는 사용가능한 로그인아이디 입니다.", loginId), "loginId", loginId);
}
<Util.java>
//숫자로만 구성된 문자열인지 여부 판별
public static boolean allNumberString(String str) {
if ( str == null ) {
return false;
}
if ( str.length() == 0 ) {
return true;
}
for ( int i = 0; i < str.length(); i++ ) {
if ( Character.isDigit(str.charAt(i)) == false ) {
return false;
}
}
//숫자로만 구성되어 있으면 true 리턴
return true;
}
//숫자로 시작하는 문자열인지 여부 판별
public static boolean startsWithNumberString(String str) {
if ( str == null ) {
return false;
}
if ( str.length() == 0 ) {
return false;
}
//숫자로 시작하는 문자열이면 true 리턴
return Character.isDigit(str.charAt(0));
}
//
public static boolean isStandardLoginIdString(String str) {
if ( str == null ) {
return false;
}
if ( str.length() == 0 ) {
return false;
}
// 조건
// 5자 이상, 20자 이하로 구성
// 숫자로 시작 금지
// _, 알파벳, 숫자로만 구성
return Pattern.matches("^[a-zA-Z]{1}[a-zA-Z0-9_]{4,19}$", str);
}