@Valid와 @Validation

·2023년 11월 11일
0

프로젝트 공부

목록 보기
32/33

Api를 통해 들어온 ReqDto를 검증하기 위한 어노테이션으로는 @Valid와 @Validation가 있다.

[요약 - @Valid와 @Validated 유효성 검증 차이]
@Validated의 기능으로 유효성 검증 그룹의 지정도 있지만 거의 사용되지 않으므로 유효성 검증 진행을 기준으로 차이를 살펴보도록 하자.

  • @Valid
    • JSR-303 자바 표준 스펙
    • 특정 ArgumentResolver를 통해 진행되어 컨트롤러 메소드의 유효성 검증만 가능하다.
    • 유효성 검증에 실패할 경우 MethodArgumentNotValidException이 발생한다.
  • @Validated
    • 자바 표준 스펙이 아닌 스프링 프레임워크가 제공하는 기능
    • AOP를 기반으로 스프링 빈의 유효성 검증을 위해 사용되며 클래스에는 @Validated를, 메소드에는 @Valid를 붙여주어야 한다.
    • 유효성 검증에 실패할 경우 ConstraintViolationException이 발생한다.

@Valid

@Valid는 JSR-303 표준 스펙(자바 진영 스펙)으로써 빈 검증기(Bean Validator)를 이용해 객체의 제약 조건을 검증하도록 지시하는 어노테이션이다.
build.gradle의 dependencies에 아래의 implementation을 추가해주어야 적용 가능하다.
implementation 'org.springframework.boot:spring-boot-starter-validation'

@Valid를 사용하는 이유

@Valid를 이용하면 service단이 아닌 객체 안에서, 들어오는 값에 대해 검증할 수 있다

@Valid시 발생하는 예외

올바르지 못한 값들이 dto를 통해 들어오는 경우 MethodArgumentNotValidException가 발생한다.

@Valid 정리 - 제약조건 어노테이션

어노테이션typevalidation
@AssertTrueBoolean, boolean값이 항상 True 여야 한다.
@DecimalMax실수 제외 숫자 클래스.지정된 최대 값보다 작거나 같아야 하는 숫자이다.String : value (max 값을 지정한다.)
@DecimalMin실수 제외 숫자 클래스.지정된 최소 값보다 크거나 같아야하는 숫자이다.String : value (min 값을 지정한다.)
@DigitsBigDecimalBigIntegerCharSequencebyte, short, int, long, 이에 대응하는 Wrapper 클래스허용된 범위 내의 숫자이다.int : integer (이 숫자에 허용되는 최대 정수 자릿수), int : fraction (이 숫자에 허용되는 최대 소수 자릿수)
@Emailnull도 valid로 간주된다.올바른 형식의 이메일 주소여야한다.
@Future시간 클래스Now 보다 미래의 날짜, 시간
@FutureOrPresent시간 클래스Now의 시간이거나 미래의 날짜, 시간
@Max실수 제외 숫자 클래스.지정된 최대 값보다 작거나 같은 숫자이다.long : value (max 값을 지정한다)
@Min실수 제외 숫자 클래스.지정된 최소 값보다 크거나 같은 숫자이다.long : value (min 값을 지정한다)
@Negative숫자 클래스음수인 값이다.
@NegativeOrZero숫자 클래스0이거나 음수인 값이다
@NotBlanknull 이 아닌 값이다.공백이 아닌 문자를 하나 이상 포함한다
@NotEmptyCharSequence,Collection, Map, Arraynull이거나 empty(빈 문자열)가 아니어야 한다.
@NotNull어떤 타입이든 수용한다.null 이 아닌 값이다.
@Null어떤 타입이든 수용한다.null 값이다.
@Past시간 클래스Now보다 과거의 날짜, 시간
@PastOrPresent시간클래스Now의 시간이거나 과거의 날짜, 시간
@Pattern문자열 지정한 정규식과 대응되는 문자열이어야한다.Java의 Pattern 패키지의 컨벤션을 따른다String : regexp (정규식 문자열을 지정한다)
@Positive숫자 클래스양수인 값이다
@PositiveOrZero숫자 클래스0이거나 양수인 값이다.
@SizeCharSequence,Collection, Map, Array이 크기가 지정된 경계(포함) 사이에 있어야한다.int : max (element의 크기가 작거나 같다), int : min (element의 크기가 크거나 같다)

@Validated

@Validated는 AOP 기반으로 메소드의 요청을 가로채서 유효성 검증을 진행해주는 JSR 표준 기술이 아닌 Spring 프레임워크에서 제공하는 어노테이션 및 기능이다.
출처: https://mangkyu.tistory.com/174 [MangKyu's Diary:티스토리]

@Validated시 발생하는 예외

이전의 MethodArgumentNotValidException 예외가 아닌 ConstraintViolationException 예외가 발생한다.

@Validated의 기능

동일한 클래스에 대해 제약조건이 요청에 따라 달라질 수 있다.
이때 Stpring은 이를 위해 제약조건이 적용될 검증 그룹을 지정할 수 있도록 제공한다.

  • @Validated에 특정 클래스를 지정하지 않는 경우: groups가 없는 속성들만 처리 
  • @Valid or @Validated에 특정 클래스를 지정한 경우: 지정된 클래스를 groups로 가진 제약사항만 처리

검증 그룹 지정

아래와 같이 제약 조건이 적용될 그룹을 groups로 지정해줄 수 있다.
여러 개라면 {}를 이용해 지정이 가능하다.

@NotEmpty(groups = {UserValidationGroup.class, AdminValidationGroup.class} ) 
private String name; 

@NotEmpty(groups = UserValidationGroup.class) 
private String userId; 

@NotEmpty(groups = AdminValidationGroup.class) 
private String adminId;

그리고 컨트롤러에서도 다음과 같이 제약조건 검증을 적용할 클래스를 지정해주면 된다.

@PostMapping("/users") 
public ResponseEntity<Void> addUser(
    @RequestBody @Validated(UserValidationGroup.class) AddUserRequest addUserRequest) {
    
      ...
}

@Validated 정리 - 제약조건 어노테이션

  • @NotNull: 해당 값이 null이 아닌지 검증함
  • @NotEmpty: 해당 값이 null이 아니고, 빈 스트링("") 아닌지 검증함(" "은 허용됨)
  • @NotBlank: 해당 값이 null이 아니고, 공백(""과 " " 모두 포함)이 아닌지 검증함
  • @AssertTrue: 해당 값이 true인지 검증함
  • @Size: 해당 값이 주어진 값 사이에 해당하는지 검증함(String, Collection, Map, Array에도 적용 가능)
  • @Min: 해당 값이 주어진 값보다 작지 않은지 검증함
  • @Max: 해당 값이 주어진 값보다 크지 않은지 검증함
  • @Pattern: 해당 값이 주어진 패턴과 일치하는지 검증함

참고
@Valid 를 이용해 @RequestBody 객체 검증하기
[Spring] @Valid와 @Validated를 이용한 유효성 검증의 동작 원리 및 사용법 예시 - (1/2)

profile
개발자가 되고싶은 낭랑 24세

0개의 댓글

관련 채용 정보