회원가입 페이지를 만들고 회원가입을 할 때 닉네임과 이메일이 중복된다면 text를 날리는 것을 구현해보자.
templates package > fragments > user > register.html 작성
- register.html - css
- register.html - html
- register.html - js 변수명 설정.
- 자바스크립트에서 문자열 정규식을 사용하기 위해서 RegExp라는 객체를 객체화해서 사용한다.
emailWarning.style.display = 'none';
submit이 발생했을 때 모든 warning에 대한 디스플레이를 none으로 설정.
if(!emailRegex.test(emailInput.value)) { emailWarning.innerText = '올바른 이메일을 입력해주세요.'; emailWarning.style.display ='inline'; ...
올바르지 않은 이메일을 하고 올바른 이메일을 작성했다고 가정하자.
그러고 나서 또 다시 올바르지 않은 이메일을 입력했다면 올바르게 입력했을 때에
'올바른 이메일을 입력해주세요' 라는 메세지를 살려두면 안되기 때문에 none으로 기본값을 설정해놓는 것이다.
올바르지 않은 이메일을 선택했을 때 if문이 true가 되면서 아래의 코드가 활성화되며 display : inline이 되서 text가 보이게 된다.
<script> if(!registerForm['agree'].checked) { alert('이용약관을 읽고 동의해주세요.'); registerForm['agree'].focus(); registerForm['agree'].select(); e.preventDefault(); return false; } </script>
이용약관 동의 체크를 하지 않았다면 경고를 띄워주자.
이제는 emailInput에서 focusout이 되었다면 Warning이 뜨도록 해보자.
원활한 코드 작성을 위해 alert로 정상적으로 실행이 되는지 확인부터 해보자.
emailInput.addEventiListener('focusout', ( ) = > {
alert('??');
})
focusout 함수가 작동이 되는 것을 확인했다면 코드를 작성해보자!
<script> emailInput.addEventListener('focusout', () => { emailWarning.style.display = 'none'; if(!emailRegex.test(emailInput.value)) { emailWarning.innerText = '올바른 이메일을 입력해주세요.'; emailWarning.style.display ='inline'; } }); </script>
- 아까 작성한 if문을 끌고와서 foucsout 됐을 때의 코드를 작성한다.
emailInput, passwordInput, passwordCheckInput, nincknameInput
이 4개에 대해서 다 작성해준다.
< 결과 >
Input에서 focusout이 됐을 때 이메일이 올바른지만 확인하는 것이 아니라
만약 이메일이 올바르다면 해당 이메일이 있는 회원이 있는지 확인해서 '이미 사용중인 이메일입니다.' 란 내용을 띄우자.
중복체크는 이메일과 닉네임만 해당되는 내용이다.
중복을 확인 할 수 있는 건 자바스크립트 혼자 할 수 없다. 이메일과 닉네임의 사용 중인지에 대한 여부는 서버가 대신 해야한다. ( => xhr 이용 )
- 중복 여부 체크를 위해 DB에 미리 사용자 한명을 등록하자.
-> UserController
@RequestMapping(value = "check-email", method = RequestMethod.POST) @ResponseBody public String postCheckEmail( UserEntity userEntity ) { }
value = "check-email"
이메일을 전달받아서 해당 이메일의 횟수를 세서 존재하는지 존재하지 않는지 확인하기 위한 맵핑을 한다.
-> UserEntity 생성
public class UserEntity { private int index; private String email; private String password; private boolean isDeleted; private Boolean isSuspended; private boolean isAdmin; private String nickname;
- UserTable을 대표할 수 있는 UserEntity 생성 + getter, setter
-> UserContoller
public String postCheckEmail ( UserEntity userEntity )
- UserContoller에서 postCheckEmail에서 UserEntity를 전달 받는다.
-> UserService
public int getCountByEmail(UserEntity userEntity) { if(userEntity.getEmail() == null || !userEntity.getEmail() .matches("^(?=.{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})?$")) { return -1; } }
- 만약 UserEntity의 getEmail이 null이거나 정규식에 맞지않다면 ( = defalut )
return -1 을 해주는 getCountByEmail 메서드를 만들어준다.- 자바에서는 문자열 객체의 mathches 메서드를 이용한다.
( <-> 자바스크립트 RegExp)
-> IUserMapper 생성
@Mapper public interface IUserMapper { int selectCountByEmail(UserEntity userEntity); }
- bbsbasic의 mappers 디렉토리안에 IUserMapper 인터페이스 생성.
-> UserMapper.xml 생성
- resources의 mappers디렉토리안에 전에 만들어놨던 xml파일을 이용해 UserMapper.xml 생성.
<mapper namespace="dev.jwkim.bbsbasic.mappers.IUserMapper"> <select id="selectCountByEmail" parameterType="dev.jwkim.bbsbasic.entities.UserEntity" resultType="_int"> SELECT COUNT(0) AS `count` FROM `spring3`.`users` WHERE `email` = #{email} </select> </mapper>
mapper태그의 namespace
속성값을 IUserMapper의 인터페이스 풀네임을 적어준다.
이 메서드의 역할을 수행하기위해서 실행할 쿼리는 select이다.
id
는 메서드 이름과 동일하게 하면 된다. 저번에 mybatis를 배우면서 SELECT1테스트를 했을 때와 차이점은 이번에는 매개변수(UserEntity)가 있다.
그 매개변수를 여기에 명시를 해줘야하는데 명시를 해주기 위한 속성의 이름은parameterType
이고 매개변수타입은 UserEntity가 들어온다. 여기서도 마찬가지도 UserEntity의 풀네임을 적어준다.
# { }
이 select쿼리가 반환할 타입은 frag 타입의 int이다 =>
resultType="_int"
으로 작성.
WHERE `email` =
여기에 사용자의 이메일이 실제로 와야하는데 #{ } 을 사용한다.
PascalCasing(단어의 첫 알파벳 대문자로 변경)을 한 다음에 앞에 get을 붙여서
그 메서드가 있다면 해당 메서드를 가져온다.
UserEntity의 get메서드 중 해당되는 것을 불러오는 것이다 .
#{ email } + get => getEmail
즉, UserEntity의 getEmail을 호출해 오는 것이다.
-> UserService
private final IUserMapper userMapper; @Autowired public UserService(IUserMapper userMapper) { this.userMapper = userMapper; }
IUserMapper라는 인터페이스를 Autowired걸어줘서 객체화를 헤준다.
public int getCountByEmail(UserEntity userEntity) { if(userEntity.getEmail() == null || !userEntity.getEmail() .matches("^(?=.{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})?$")) { return -1; } return this.userMapper.selectCountByEmail(userEntity); }
return this.userMapper.selectCountByEmail(userEntity);
추가1
-> UserController
private final UserService userService; @Autowired public UserController(UserService userService) { this.userService = userService; }
UserController에서 객체화해준다.
@RequestMapping(value = "check-email", method = RequestMethod.POST) @ResponseBody public String postCheckEmail ( UserEntity userEntity ) { return String.valueOf(this.userService.getCountByEmail(userEntity)); }
return String.valueOf(this.userService.getCountByEmail(userEntity));
추가!
여기서 코드가 잘 짜였는지 체크하고 넘어가자.
postman에서 입력한 값이 DB에 있는지 없는지 체크하는 동작이 잘 작동이 되는지 확인해보자.
1 = true = 사용중인 값 ( 사용중인 이메일 존재 )
0 = false = 사용하지 않는 값 ( 이메일 사용 가능 )
-1 = 정규식 위반. (return -1)
다시 register.html js로 넘어와서 if뒤 else로 xhr을 작성해준다.
<script>
emailInput.addEventListener('focusout', () => {
emailWarning.style.display = 'none';
if(!emailRegex.test(emailInput.value)) {
emailWarning.innerText = '올바른 이메일을 입력해주세요.';
emailWarning.style.display ='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);
}
});
</script>
< 6 / 13 result >
똑같은 이메일을 작성하였다면 '해당 이메일은 이미 사용 중 입니다' 라고 뜬다. (닉네임도 동일)
postman에서 확인을 해보면 '관리자'라고 적었을 때
1(=true, 해당 값이 DB에 존재함) 이 뜨는 것을 확인 할 수 있다.
nickname에 대해서 추가 작성한 부분을 사진으로 가지고 오겠습니다 :)
UserMapper에서 Dao처럼 Db를 가져온다.
UserService 어떻게 사용할 건지에 대해 제어해준다 .
UserController
register.html 에서 xml작성.