상세 컨텐츠

본문 제목

[JPA] 회원가입시 아이디 중복검사

JAVA/SPRING

by ranlan 2021. 4. 20. 02:23

본문

728x90

[이전] 2021.04.20 - [project/spring] - [JPA] 회원가입과 유효성 체크

 

[JPA] 회원가입과 유효성 체크

Spring Boot JPA 회원가입 [도메인 설계] 회원 정보의 내용으로 회원 가입을 위한 필수 입력 항목들은 아래와 같다. - 이름 - 아이디 - 비밀번호 - 이메일주소 - 전화번호 위 항목들을 포함하여 회원가

juran-devblog.tistory.com

 

 

회원가입 시 아이디가 기존의 사용자들이 쓰는 아이디와 겹치는지 확인해야 한다.

나는 아이디 중복 검사를 위해 아이디 입력칸 아래 아아디 중복확인 버튼을 만들었고 클릭 시 중복검사 api가 호출되도록 하였다.

 

 

 

📄 MemberRepository

@Repository
public interface MemberRepository extends JpaRepository<Member, Long> {

    boolean existsByMemberId(String memberId);
}

exists를 제공하는 JPA 덕분에 쉽게 진행하였다.

existsByXXX(찾으려는 값)은 알아서 해당 값이 존재하는지 조회하는 select 쿼리를 날려준다.

 

실행 시 발생하는 쿼리

select
        member0_.member_no as col_0_0_ 
    from
        member member0_ 
    where
        member0_.member_id=? limit ?

 

📄 MemberService

@Transactional
public boolean existsByMemberId(String memberId){
	
    return memberRepository.existsByMemberId(memberId);
}

레퍼지토리에서 정의한 메서드로 서비스를 구현한다.

파라미터로 받은 memberId가 DB에 존재하는 경우 true를 반환하고 없을 경우 false를 반환한다.

 

📄 MemberApiController

@GetMapping("/id/check")
public ResponseEntity<?> checkIdDuplication(@RequestParam(value = "memberId") String memberId) throws BadRequestException {
    System.out.println(memberId);

    if (memberService.existsByMemberId(memberId) == true) {
    	throw new BadRequestException("이미 사용중인 아이디 입니다.");
    } else {
        return ResponseEntity.ok("사용 가능한 아이디 입니다.");
    }
}

아이디 중복검사 버튼을 눌렀을 때와 회원가입 버튼을 눌렀을 때 호출될 API다.

서비스에 구현된 메서드의 반환값에 맞춰 사용자에게 보여줄 메시지를 설정하였다.

  • 레퍼지토리의 반환값이 True일 경우(아이디가 존재할 때) 해당 아이디가 사용 불가능함으로 Exception
  • 레퍼지토리의 반환값이 False일 경우(아이디가 존재하지 않을 때) 해당 아이디가 사용 가능함으로 ResponseEntity.ok 성공 응답

 

여기서 BadRequestException 은 잘못된 요청을 했을 때 예외처리를 위한 Exception 객체로 RuntimeException을 상속받는다.

 

📄 BadRequestExceptioin

@ResponseStatus(value = HttpStatus.CONFLICT, reason = "Already exists")
public class BadRequestException extends RuntimeException {

    public BadRequestException(String message) {
        super(message);
    }
}

📄 RuntimeException

/**
 * {@code RuntimeException} is the superclass of those
 * exceptions that can be thrown during the normal operation of the
 * Java Virtual Machine.
 *
 * <p>{@code RuntimeException} and its subclasses are <em>unchecked
 * exceptions</em>.  Unchecked exceptions do <em>not</em> need to be
 * declared in a method or constructor's {@code throws} clause if they
 * can be thrown by the execution of the method or constructor and
 * propagate outside the method or constructor boundary.
 *
 * @author  Frank Yellin
 * @jls 11.2 Compile-Time Checking of Exceptions
 * @since   1.0
 */
 
public class RuntimeException extends Exception {
    static final long serialVersionUID = -7034897190745766939L;

    public RuntimeException() {
        super();
    }

    public RuntimeException(String message) {
        super(message);
    }

    public RuntimeException(String message, Throwable cause) {
        super(message, cause);
    }

    public RuntimeException(Throwable cause) {
        super(cause);
    }

    protected RuntimeException(String message, Throwable cause,
                               boolean enableSuppression,
                               boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

위와 같은 정보들을 전달할 수 있다.

 

 

JSP & Javascript

이제 화면에서 중복검사 결과를 알려줘야 한다.

 

📄 JSP

<d id="idAvailable" class="valid-feedback" style="display: none;"></d>
<d id="idNotAvailable" class="invalid-feedback" style="display: none;"></d>

성공과 실패 시 메시지가 나오는 부분의 클래스가 달라 둘 다 만들어놓은 뒤 안보이게 처리해 두고 상황에 맞춰 필요한 d가 보이도록 하였다.

 

📄JavaScript

중복검사를 위한 API를 호출하는 ajax 부분

$.ajax({
    url: baseUrl + '/api/member/id/check',
    type: 'GET',
    contentType: 'application/json',
    headers: {
    	// 스프링 시큐리티를 위한 헤더 설정
    	"X-CSRF-TOKEN": $("meta[name='_csrf']").attr("content")
    },
    data: {
    	memberId: $('#memberId').val()
    },
    success: function (result) {
    	// 성공 시 실패 메시지 hide, 성공 메시지 show
        $('#idNotAvailable').hide();
        $('#idAvailable').show().text(result).append($('<br />'));
    }, error: function(error) {
    	// 실패 시 실패 메시지 show, 성공 메시지 hide
        $('#idAvailable').hide();
        $('#idNotAvailable').show().text('이미 사용중인 아이디 입니다.').append($('<br />'));
    }
});

중복확인 통과o
중복확인 통과x

 

회원가입 버튼을 눌렀을 때도 동일하게 api가 호출되며 ajax 성공시 전 포스팅에 있던 회원가입 API를 호출하도록 하였다.

 

 

++ ) 수정

이미 등록된 아이디일 경우 BadRequestException 에 관련 메시지를 담아 반환하였었다.

또 다른 예외 경우도 생각하여 예외 처리할 때 정의한 메세지를 바로 화면에 보여주고 싶었는데 반환된 에러에서 메시지를 어떻게 받아야 하는지 몰라 똑같은 메시지를 직접 화면에 스크립트로 작성했었다.

 

해결 방법은 간단하였다.

에러 발생시 ResponseJson에 메시지가 BadRequestException에서 설정했던 reason = "Already exists" 이길래 이를 지우니 내가 설정한 메시지로 받을 수 있었다.

 

📄 BadRequestException

@ResponseStatus(value = HttpStatus.CONFLICT)
public class BadRequestException extends RuntimeException {

    public BadRequestException(String message) {
        super(message);
    }

}

📄 JSP & Javascript

$.ajax({
    url: baseUrl + '/api/member/id/check',
    type: 'GET',
    contentType: 'application/json',
    headers: {
    	// 스프링 시큐리티 헤더 설정
    	"X-CSRF-TOKEN": $("meta[name='_csrf']").attr("content")
    },
    data: {
    	memberId: $('#memberId').val()
    },
    success: function (result) {
    	// 아이디 중복검사 성공 시(중복된 아이디가 존재하지 않을 시) 해당 아이디 사용 가능 문구 출력
        $('#idNotAvailable').hide();
        $('#idAvailable').show().text(result).append($('<br />'));
    }, error: function(error) {
    	// 아이디 중복검사 실패 시(중복된 아이디가 존재할 시) Exception객체에 담긴 해당 아이디 사용 불가능 안내 문구 출력
        $('#idAvailable').hide();
        $('#idNotAvailable').show().text(error.responseJSON['message']).append($('<br />'));
    }
});

 

동일 아이디 존재 시 ajax 호출 결과 받은 BadRequestException 중 responseJson

 

Response

 

728x90

관련글 더보기

댓글 영역