bbs-basic - 2, 회원가입 page구현 및 이메일, 닉네임 사용 가능 여부 체크.

김지원·2022년 6월 14일
0

WebDevelop

목록 보기
3/21

회원가입 페이지를 만들고 회원가입을 할 때 닉네임과 이메일이 중복된다면 text를 날리는 것을 구현해보자.

templates package > fragments > user > register.html 작성

  • register.html - css
  • register.html - html

submit이 발생했을 때 조치에 대한 코드 작성.

  • 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>

이용약관 동의 체크를 하지 않았다면 경고를 띄워주자.


Focusout 함수 작성 (Warning)

이제는 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개에 대해서 다 작성해준다.

< 결과 >


이미 사용중인 정보에 대한 처리 (xhr)

Input에서 focusout이 됐을 때 이메일이 올바른지만 확인하는 것이 아니라
만약 이메일이 올바르다면 해당 이메일이 있는 회원이 있는지 확인해서 '이미 사용중인 이메일입니다.' 란 내용을 띄우자.

  • 텍스트를 innerText로 작성했던 이유는 지금처럼 다르게 사용 될 우려가 있기 때문이였다.

중복체크는 이메일과 닉네임만 해당되는 내용이다.
중복을 확인 할 수 있는 건 자바스크립트 혼자 할 수 없다. 이메일과 닉네임의 사용 중인지에 대한 여부는 서버가 대신 해야한다. ( => 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에 대해서 추가 작성한 부분을 사진으로 가지고 오겠습니다 :)

  1. UserEntity에서 data생성한다.

  • getter,setter도 생성.
  1. IUserMapper 메소드 생성

  • selectCountByNickname / UserEntity를 매개변수로 갖는다.
  1. UserMapper에서 Dao처럼 Db를 가져온다.

  2. UserService 어떻게 사용할 건지에 대해 제어해준다 .

  1. UserController

  2. register.html 에서 xml작성.

0개의 댓글