Chef.Yeon
Code Cook
Chef.Yeon
전체 방문자
오늘
어제
  • 분류 전체보기 (230)
    • 게임 개발 (1)
      • Unity (1)
    • Android (27)
      • Kotlin (19)
      • 우아한테크코스 5기 (4)
    • Language (11)
      • 파이썬 (3)
      • Java (7)
    • DB (2)
      • SQL (16)
    • Spring (25)
    • 코딩테스트 (56)
    • Git (1)
    • TIL (85)
    • DevOps (6)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • spring
  • kibana
  • Wil
  • elasticsearch
  • 코틀린
  • 에라토스테네스의 체
  • 레포지토리
  • 프리코스
  • enum
  • grafana
  • 다이나믹 프로그래밍
  • 우아한테크코스
  • 내림차순
  • til
  • kotlin
  • 코딩테스트
  • 파이썬
  • webflux
  • rsocket
  • 코틀린 인 액션
  • 문자열
  • SQL
  • Docker
  • 프로그래머스
  • java
  • MariaDB
  • 백준
  • ec2
  • 안드로이드
  • Android

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Chef.Yeon

Code Cook

Spring

[Spring] @Valid를 사용한 객체 유효성 검증

2023. 4. 22. 23:05

구성은 다음과 같다.

 

MemberController

@RestController
@RequestMapping("member")
@RequiredArgsConstructor
public class MemberController {

    private final MemberService memberService;

    @PostMapping("/signup")
    public ResponseEntity signup(@Valid @RequestBody SignupRequestDto signupRequestDto) {
        return memberService.signup(signupRequestDto);
    }
}

 

SignupRequestDto

@Getter
@Setter
public class SignupRequestDto {
    private String userId;
    private String password;
}

 

Member

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Member {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(nullable = false)
    private String userId;
    @Column(nullable = false)
    private String password;

    public Member(SignupRequestDto requestDto) {
        this.userId = requestDto.getUserId();
        this.password= requestDto.getPassword();
    }
}

 

MemberRepository

public interface MemberRepository extends JpaRepository<Member, Long> {
}

 

MemberService

@Service
@RequiredArgsConstructor
public class MemberService {

    private final MemberRepository memberRepository;
    
    /**
     * 회원가입
     */
    public ResponseEntity signup(SignupRequestDto requestDto) {
        Member member = new Member(requestDto);
        memberRepository.save(member);
        return new ResponseEntity(member, HttpStatus.OK);
    }
}

 

PostMan을 통해 확인해보자.

 

여기서 사용자가 입력한 아이디와 비밀번호의 유효성을 검증하고 싶다면 다음과 같이 작성할 수 있다.

 

MemberService

@Service
@RequiredArgsConstructor
public class MemberService {

    private final MemberRepository memberRepository;
    /**
     * 회원가입
     */
    public ResponseEntity signup(SignupRequestDto requestDto) {
        String userId = requestDto.getUserId();
        String password = requestDto.getPassword();

        if (userId == null || password == null) {
            throw new IllegalArgumentException("아이디 또는 비밀번호는 필수 입니다.");
        }

        if (userId.length() < 4 || userId.length() > 11 ) {
            throw new IllegalArgumentException("아이디는 4~10자리로 입력해주세요.");
        }

        if (!(Pattern.matches("^[a-z0-9]{4,10}$", userId))){
            throw new IllegalArgumentException("아이디는 4~10자리 영문 소문자와 숫자로 이루어져야 합니다.");
        }

        if (!Pattern.matches("^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*\\W)(?=\\S+$).{8,15}", password)){
            throw new IllegalArgumentException("비밀번호는 8~15자리 영문 대소문자, 숫자, 특수문자로 이루어져야 합니다.");
        }

        Member member = new Member(requestDto);
        memberRepository.save(member);
        return new ResponseEntity(member, HttpStatus.OK);
    }
}

 

다음과 같이 회원가입을 시도하면 에러가 발생하는 것을 볼 수 있다.

 

하지만 이런식으로 검증하게 되면, 로직이 길어질 수 밖에 없다. 

스프링에서는 @Valid를 사용하여 클라이언트에서 넘어온 데이터를 객체와 바인딩할 때 유효성 검사를 할 수 있다.

 

728x90

 

@Valid

@Valid를 사용하기 위해 build.gradle에 다음을 추가해준다.

implementation 'org.springframework.boot:spring-boot-starter-validation'

 

다음과 같이 SignupRequestDto에서 유효성 검사를 할 필드에 애노테이션을 추가해준다. 

@Getter
@Setter
public class SignupRequestDto {

    @NotBlank
    @Size(min = 4, max = 10)
    @Pattern(regexp = "^[a-z0-9]*$")
    private String userId;

    @NotBlank
    @Size(min = 8, max = 15)
    @Pattern(regexp = "(?=.*[0-9])(?=.*[a-zA-Z])(?=.*\\W)(?=\\S+$).{8,15}")
    private String password;
}

 

그리고 MemberController에서 검증할 매개변수 앞에 @Valid를 붙여준다.

@RestController
@RequestMapping("member")
@RequiredArgsConstructor
public class MemberController {

    private final MemberService memberService;

    @PostMapping("/signup")
    public ResponseEntity signup(@Valid @RequestBody SignupRequestDto signupRequestDto) {
        return memberService.signup(signupRequestDto);
    }
}

 

PostMan에서 비밀번호 형식이 올바르지 않은 데이터를 보내면 다음과 같은 에러가 발생한다.

 

Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public org.springframework.http.ResponseEntity com.example.sample.controller.MemberController.signup(com.example.sample.dto.SignupRequestDto) with 2 errors: [Field error in object 'signupRequestDto' on field 'password': rejected value [1234]; codes [Size.signupRequestDto.password,Size.password,Size.java.lang.String,Size]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [signupRequestDto.password,password]; arguments []; default message [password],15,8]; default message [크기가 8에서 15 사이여야 합니다]] [Field error in object 'signupRequestDto' on field 'password': rejected value [1234]; codes [Pattern.signupRequestDto.password,Pattern.password,Pattern.java.lang.String,Pattern]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [signupRequestDto.password,password]; arguments []; default message [password],[Ljakarta.validation.constraints.Pattern$Flag;@13eaf9f9,(?=.*[0-9])(?=.*[a-zA-Z])(?=.*\W)(?=\S+$).{8,15}]; default message ["(?=.*[0-9])(?=.*[a-zA-Z])(?=.*\W)(?=\S+$).{8,15}"와 일치해야 합니다]] ]

 

@Valid 종류

@NotNull Null이 아닌 값
@Null Null인 값
@NotBlank Null이 아닌 값, 공백이 아닌 문자 하나 이상 포함
@NotEmpty Null이 아닌 값, 빈 문자열이 아닌 값
@Size(min = , max = ) 문자열 길이가 min 이상 max 이하인 값
@Max(value = ) max 이하의 값
@Min(value = ) min 이하의 값
@Email 이메일 형식의 값
@Positive 양수인 값
@PositiveOrZero 양수 또는 0인 값
@Negative 음수인 값
@NegativeOrZero 음수 또는 0인 값
@Future 현재보다 미래의 날짜, 시간
@Past 현재보다 과거의 날짜, 시간
@PastOrPresent 현재 또는 과거의 날짜, 시간
@Pattern(regex = ) 정규식 검증
@AssertTrue true인 값
@AssertFalse false인 값
@Degits(integer = , fraction = ) 정수 자리수 integer 값 이하, 소수 자리수 fraction 값 이하
@DecimalMax(value = ) value 이하의 값
@DecimalMin(value = ) value 이상의 값

 

728x90

'Spring' 카테고리의 다른 글

[Spring] AWS RDS MariaDB + Spring Boot, Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (utf8mb4_unicode_ci,COERCIBLE) for operation '=' 해결  (0) 2023.05.08
[Spring] @Valid 메시지 message properties 사용하기, 한글 깨짐 해결  (0) 2023.04.27
[Spring] @Valid @ControllerAdvice와 @ExceptionHandler 사용한 전역 예외 처리  (0) 2023.04.25
[Spring] Spring profiles 통한 DB/개인정보 .gitignore에 추가하기  (0) 2023.04.11
[Spring] SpringBoot 프로젝트에서 MariaDB 사용하기, 간단한 테스트  (0) 2023.04.04
    'Spring' 카테고리의 다른 글
    • [Spring] @Valid 메시지 message properties 사용하기, 한글 깨짐 해결
    • [Spring] @Valid @ControllerAdvice와 @ExceptionHandler 사용한 전역 예외 처리
    • [Spring] Spring profiles 통한 DB/개인정보 .gitignore에 추가하기
    • [Spring] SpringBoot 프로젝트에서 MariaDB 사용하기, 간단한 테스트
    Chef.Yeon
    Chef.Yeon
    보기 좋고 깔끔한 코드를 요리하기 위해 노력하고 있습니다.

    티스토리툴바