본문 바로가기
Java/Spring

[Spring]@Validation @valid 어노테이션

by 전재경 2022. 12. 8.

@Validation 어노테이션

Bean Validation이라는 데이터 유효성 검사 프레임워크를 제공

 

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

 

springboot가 버전업을 하면서 web 의존성안에 있던 constraints packeage가 아예 모듈로 빠졌다.

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

 

유효성 검사에 사용할 수 있는 어노테이션

@AssertFalse -> 주석이 달린 요소는 거짓이어야한다.
@AssertTrue -> 주석이 달린 요소는 참이어야한다.
@Email -> 주석이 달린 문자열은 이메일 형식이어야한다.
@Future -> 주석이 달린 요서는 미래의 날짜, 또는 시간이어야한다.
@Past -> 주석이 달린 요서는 과거의 순간, 날짜 또는 시간이어야한다.
@Max(value=) -> 주석이 달린 요소는 value보다 작거나 같아야한다.
@Min(value=) -> 주석이 달린 요소는 value보다 크거나 같아야한다.
@NotBlank -> 주석이 달린 요소는 Null이 아니어야하며 하나 이상의 공백이 아닌 문자를 포함해야한다.
@NotEmpty -> 주석이 달린 요서는 Null이거나 비어있으면 안된다.
@Pattern(regexp=, message=) -> 주석이 달린 문자열은 regexp에 지정된 정규식과 일치하여야한다.
@Size(min=, max=) -> 주석이 달린 요소의 크기는 해당 범위 내에 있어야한다.

 

@Valid, @Validated 차이

  @Validated는 @Valid의 기능을 포함한다. 쉽게 @Valid를 적용한 곳이라면 이는 @Validated로 변경 가능하다.

  더하여 @Validated는 검토할 검토 옵션의 그룹을 지정할 수 있다.

 

@Valid를 사용하는 방법

간단한 API를 작성해보자.

@RestController
@Slf4j
public class TestController {

    @PostMapping("/user")
    public ResponseEntity<String> savePost(final @Valid @RequestBody UserDto userDto) {
        log.info(userDto.toString());
        return ResponseEntity.ok().body("postDto 객체 검증 성공");
    }
}

파라미터로 @RequestBody 어노테이션 옆에 @Valid를 작성하면, RequestBody로 들어오는 객체에 대한 검증을 수행한다. 이 검증의 세부적인 사항은 객체 안에 정의를 해두어야 한다.

@ToString
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class UserDto {

    @NotNull
    private String name;
    
    @Email
    private String email;
}

위와 같이 UserDto 객체를 정의한 후 각 필드에 맞는 어노테이션을 사용하면 된다.

 

예시 코드 

검토 옵션 그룹

@Getter @Setter
public class Member{
  interface validGroupA {}
  interface validGroupB {}
  
  @NotBlank(groups = validGroupA.class)
  private String name;
  
  @Min(value = 0, groups = validGroupB.class)
  private String age;
}

 

검토 사용

@RestController
public class SampleController {
    @GetMapping(value="/hello")
    public String hello(@Validated(Member.validGroupA.class) Member member, BindingResult br){
        if(br.hasError){System.out.println("error - groupA");}
        return member;
    }
}

 

@Valid 정리 표

@AssertTrue Boolean, boolean 값이 항상 True 여야 한다.  
@DecimalMax 실수 제외 숫자 클래스. 지정된 최대 값보다 작거나 같아야 하는
숫자이다.
String : value
(max 값을 지정한다.)
@DecimalMin 실수 제외 숫자 클래스. 지정된 최소 값보다 크거나 같아야하는
숫자이다.
String : value
(min 값을 지정한다.)
@Digits BigDecimalBigIntegerCharSequencebyte, short, int, long, 이에 대응하는 Wrapper 클래스 허용된 범위 내의 숫자이다. int : integer (이 숫자에 허용되는 최대 정수 자릿수)

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

int : min (element의 크기가 크거나 같다)

 

@Valid시 발생하는 Exception Handling 

@Valid로 requestBody로 들어온 객체의 검증이 이루어지면서 위와 같이 BadRequest가 나가는 경우에 custom 한 errorhandling도 할 수 있다. 

 

@ControllerAdvice를 이용한 전역 에러 핸들링, 혹은 @Controller단에서의 지역 에러 핸들링을 사용하면 된다.

댓글