[이전] 2021.04.20 - [project/spring] - [JPA] 회원가입과 유효성 체크
회원가입 시 아이디가 기존의 사용자들이 쓰는 아이디와 겹치는지 확인해야 한다.
나는 아이디 중복 검사를 위해 아이디 입력칸 아래 아아디 중복확인 버튼을 만들었고 클릭 시 중복검사 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다.
서비스에 구현된 메서드의 반환값에 맞춰 사용자에게 보여줄 메시지를 설정하였다.
여기서 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
<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 />'));
}
});
회원가입 버튼을 눌렀을 때도 동일하게 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
[JPA] 사용자 비밀번호 확인과 정보 수정 (0) | 2021.04.29 |
---|---|
[ERROR] 스프링부트 테스트 IllegalStateException (0) | 2021.04.29 |
[JPA] 회원가입과 유효성 체크 (0) | 2021.04.20 |
[SPRING SECURITY] CSRF (0) | 2021.04.16 |
[SPRING SECURITY] 커스텀 클래스와 로그인 (0) | 2021.04.16 |
댓글 영역