[스프링부트 게시판] 25. 회원가입시 validation 체크

2022. 6. 30. 17:25·🚗 Backend Toy Project/스프링 부트 게시판

회원가입시에 아이디, 비밀번호, 이메일의 형식을 따로 정해두고 해당 형식에 맞지 않으면 회원가입을 할 수 없도록 유효성 검사를 구현해주었습니다. 인터넷에 나와 있는 자료를 바탕으로 여러가지 방법을 시도해보았으나 잘 작동하지 않는 경우가 대부분이었는데, 이틀정도 구르다보니 어찌저찌 그럴듯 하게 동작하도록 구현은 된 것 같습니다.

 

유효성 검사를 위한 구현 과정은 다음과 같습니다.


📝 1. UserRequestDto

  • 우선 기존에 ajax에서 엔티티를 통해 데이터를 받아오던 방식에서 따로 DTO를 만들어 데이터를 받아오는 방식으로 수정하였습니다.
  • 이유는 여러가지가 있는데, 가장 큰 이유는 애초에 엔티티로 유효성 검사를 수행하려 할 경우 오류가 발생하였습니다. 오류가 발생한 정확한 이유는 모르겠으나 위처럼 수정하니 오류가 해결되었습니다.
  • DTO 구성은 아래와 같습니다.
package com.cos.blog.dto;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class UserRequestDto {

	@NotBlank(message = "아이디는 필수 입력 값입니다.")
	private String username;
	
	@NotBlank(message = "비밀번호는 필수 입력 값입니다.")
	@Pattern(regexp = "(?=.*[0-9])(?=.*[a-zA-Z])(?=.*\\W)(?=\\S+$).{8,16}", message = "비밀번호는 8~16자 영문 대 소문자, 숫자, 특수문자를 사용하세요.")
	private String password;
	
	@NotBlank(message = "이메일은 필수 입력 값입니다.")
	@Pattern(regexp = "^(?:\\w+\\.?)*\\w+@(?:\\w+\\.)+\\w+$", message = "이메일 형식이 올바르지 않습니다.")
	private String email;
}

📝 2. Controller 수정

  • 이에따라 Controller의 회원가입 부분을 아래와 같이 수정해주었습니다.
@PostMapping("/auth/joinProc")
public ResponseDto<?> join(@Valid @RequestBody UserRequestDto userDto, BindingResult bindingResult) {
    if(bindingResult.hasErrors()) {
        Map<String, String> validatorResult = userService.validateHandling(bindingResult);

        return new ResponseDto<>(HttpStatus.BAD_REQUEST.value(), validatorResult);
    }

    userService.join(userDto);
    return new ResponseDto<Integer>(HttpStatus.OK.value(), 1);
}
  • BindingResult는 스프링이 제공하는 객체로, 검증 오류가 발생할 시 해당 내용을 저장하는 객체입니다.
  • 주의할 점으로, BindingResult 객체는 @Valid 어노테이션이 붙은 변수 뒤에, 즉 유효성 검사를 수행하고자 하는 객체의 바로 뒤에 선언해주어야 합니다.
  • 이렇게 BindingResult를 사용하면 400 오류가 발생하지 않고 오류 내용을 따로 담아 컨트롤러를 정상 호출할 수 있기 때문에 오류 페이지로 넘어가기 전에 이에 대한 처리를 수행할 수 있습니다.
if(bindingResult.hasErrors()) {
    Map<String, String> validatorResult = userService.validateHandling(bindingResult);

    return new ResponseDto<>(HttpStatus.BAD_REQUEST.value(), validatorResult);
}
  • hasErrors() 메서드는 유효성 검사를 통해 발생한 오류가 있는지를(유효성 검사에 실패했는지를) 체크하는 메서드입니다.
  • validateHandling() 메서드는 Controller에서 발생한 에러를 전달받아 알맞게 정재한 뒤에 다시 반환해주는 함수로, 이렇게 정재된 반환값은 이후 View에서 사용할 것입니다.
  • validateHandling() 메서드는 Service단에 아래와 같이 구현되어 있습니다.
@Transactional(readOnly = true)
public Map<String, String> validateHandling(BindingResult bindingResult) {
    Map<String, String> validatorResult = new HashMap<>();

    for(FieldError error : bindingResult.getFieldErrors()) {
        String validKeyName = String.format("valid_%s", error.getField());
        validatorResult.put(validKeyName, error.getDefaultMessage());
    }

    return validatorResult;
}
  • 위 메서드는 유효성 검사에 실패한 필드들을 Map 자료구조를 통해 {키 값, 에러 메시지}의 형태로 응답합니다.
    • Key : valid_{dto 필드명}
    • Message : dto에서 작성한 message 값

📝 3. Service 수정

  • 다음으로 Service 클래스는 아래와 같이 수정해주었습니다.
@Transactional
public void join(UserRequestDto userDto) {
    User user = User.builder()
            .username(userDto.getUsername())
            .password(encoder.encode(userDto.getPassword()))
            .email(userDto.getEmail())
            .role(RoleType.USER)
            .build();

    userRepository.save(user);
}

@Transactional
public void join(User user) {		
    userRepository.save(user);
}
  • 굳이 똑같은 이름의 메서드를 두 개 구현한 이유는 join 함수의 파라미터가 UserRequestDto로 변경되면서 이전에 구현한 카카오 로그인 기능도 수정해주어야 했기 때문입니다.
  • 위의 join 함수는 일반 회원가입시에 호출될 함수이고 아래의 join 함수는 카카오 로그인시에 호출될 함수입니다.

📝 4. JS 수정

  • 이제 Controller에서 반환한 Data를 js 파일에서 사용해야 하는데, 이는 아래와 같이 구현하였습니다.
$.ajax({
    type: "POST",
    url: "/auth/joinProc",
    data: JSON.stringify(data),
    contentType: "application/json; charset=utf-8",
    //dataType: "json"
}).done(function(resp) {
    if(resp.status == 400) {
        alert("회원가입 입력 정보를 다시 확인해주십시오.")

        if(resp.data.hasOwnProperty('valid_username')){
            $('#valid_username').text(resp.data.valid_username);
            $('#valid_username').css('color', 'red');
        }
        else $('#valid_username').text('');

        if(resp.data.hasOwnProperty('valid_password')){
            $('#valid_password').text(resp.data.valid_password);
            $('#valid_password').css('color', 'red');
        }
        else $('#valid_password').text('');

        if(resp.data.hasOwnProperty('valid_email')){
            $('#valid_email').text(resp.data.valid_email);
            $('#valid_email').css('color', 'red');
        }
        else $('#valid_email').text('');
    }
    else {
        alert("회원가입이 완료되었습니다.");
        location.href = "/";	
    }
}).fail(function(error) {
    alert(JSON.stringify(error));
});
  • 즉, 유효성 검사 실패 유형에 따라 알맞은 에러 메시지를 사용자에게 출력하는 것입니다.

📝 5. View 수정

  • 이제 View를 아래와 같이 수정해주면 끝납니다.
  • id 속성이 'valid_%'의 형태로 되어있는 <p> 태그를 추가하였으며, 해당 위치에 오류 메시지가 출력될 것입니다.
<div class="container">
	<form>
		<div class="form-group">
			<label for="username">Username</label> <input type="text" class="form-control" placeholder="Enter username" id="username">
		</div>
		<p id="valid_username"></p>
		<div class="form-group">
			<label for="password">Password</label> <input type="password" class="form-control" placeholder="Enter password" id="password">
		</div>
		<p id="valid_password"></p>
		<div class="form-group">
			<label for="email">Email address</label> <input type="email" class="form-control" placeholder="Enter email" id="email">
		</div>
		<p id="valid_email"></p>
	</form>
	<button id="btn-join" class="btn btn-primary">Join</button>
</div>

📝 6. 결과 확인


💡 알게 된 점

  • @Valid 어노테이션과 BindingResult 객체를 사용하여 유효성 검사를 수행하는 방법
  • 유효성 검사 이후 실패 조건에 따라 서로 다른 오류 메시지를 클라이언트 측에 전달하는 방법
 

GitHub - Daegwon-Kim/SpringBoot-JPA-Blog

Contribute to Daegwon-Kim/SpringBoot-JPA-Blog development by creating an account on GitHub.

github.com

 

저작자표시 (새창열림)

'🚗 Backend Toy Project > 스프링 부트 게시판' 카테고리의 다른 글

[스프링부트 게시판] 27. 게시글 작성일 및 조회수 추가  (0) 2022.07.03
[스프링부트 게시판] 26. 커스텀 Validation을 통한 중복 검사 구현  (0) 2022.07.02
[스프링부트 게시판] 24. Remember Me 기능 구현  (0) 2022.06.29
[스프링부트 게시판] 23. 로그인 실패 예외 처리  (0) 2022.06.28
[스프링부트 게시판] 22. 개선 및 수정사항  (0) 2022.06.25
'🚗 Backend Toy Project/스프링 부트 게시판' 카테고리의 다른 글
  • [스프링부트 게시판] 27. 게시글 작성일 및 조회수 추가
  • [스프링부트 게시판] 26. 커스텀 Validation을 통한 중복 검사 구현
  • [스프링부트 게시판] 24. Remember Me 기능 구현
  • [스프링부트 게시판] 23. 로그인 실패 예외 처리
Baeg-won
Baeg-won
  • Baeg-won
    좋았다면 추억이고 나빴다면 경험이다.
    Baeg-won
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 🍃 Spring, Spring Boot
        • 스프링 프레임워크 기초
        • 스프링 핵심 원리 - 기본편
        • 자바 ORM 표준 JPA 프로그래밍 - 기본편
        • 스프링 MVC
        • 실전! 스프링 부트와 JPA 활용1 - 웹 애플리..
      • 🥑 Web Technoloy
      • 🚗 Backend Toy Project
        • 스프링 부트 게시판
        • Photogram
        • Baeg-won Clothing Gallery
      • 🥇 Problem Solving
        • Breadth-First Search
        • Depth-First Search
        • Backtracking
        • Simulation
        • Two-pointer
        • Binary Search
        • Greedy
        • Dynamic Programming
        • Minimum Spanning Tree
        • Dijkstra
        • Floyd warshall
      • ☕ Java
        • 명품 자바 에센셜
        • Applications
      • 🍦 JavaScript
        • JavaScript 기초
      • 🐧 Linux
        • 이것이 리눅스다(CentOS 8)
      • 📟 Database
        • 혼자 공부하는 SQL
      • 🧬 Data Structure
      • 🎬 HTML
      • 🎤 Tech Interview
      • 📌 etc
        • Unity 2D Raising Jelly Game
        • C++
        • 영어 쉐도잉
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Baeg-won
[스프링부트 게시판] 25. 회원가입시 validation 체크
상단으로

티스토리툴바