Spring/SpringMVC

Bean Validation Annotation 종류

ysk(0soo) 2022. 12. 28. 18:22

Bean Validation이란?

특정 구현체가 아닌 Bean Validation 2.0(JSR-380)이라는 기술 표준으로 여러 검증 애노테이션과 여러 인터페이스의 모음이다.

  • javax.validation 패키지였지만 현재는 jakarta.validation 패키지이다.
  • Jakarta Bean Validation 2.0 - Java 8 이상
  • Jakarta Bean Validation 3.0 - Java 11 이상

Spring Boot 3.0.0 M1 릴리스 노트 에서
Spring Boot 2.X는 Jakarta EE를 지원하지 않지만 Spring Boot 3.X에서는 지원이 제공된다.

  • Spring Boot 2.X의 경우 javax.
  • Spring Boot 3.X의 경우 jakarta. 를 사용해야 한다.

이러한 Bean Validation을 구현한 기술중 일반적으로 사용하는 구현체는 하이버네이트 Validator이다.

(이름이 하이버네이트지만 ORM과는 관련없다. )

Bean Validation 를 활용하면 어노테이션 기반으로 우리가 구현했던 각종 구현로직들을 간단하게 적용할 수 있다.

스프링 프레임워크에서 제공하는 유효성 라이브러리를 사용하기위해서는 gradle의 dependecy에 추가해야만 한다.

dependencies{
    implementation 'org.springframework.boot:spring-boot-starter-validation'
}
  • 이 의존성을 추가하지 않으면 동작하지 않는다.

Spring Boot AutoConfigruation With Validator

Spring Boot ValidationAutoConfiguration 클래스를 통해서

LocalValidatorFactoryBeanMethodValidationPostProcessor를 자동으로 설정한다.

LocalValidatorFactoryBean는 Spring에서 Validator를 사용하기 위해서 필요하고
MethodValidationPostProcessor는 메서드 파라미터 또는 리턴 값을 검증하기 위해서 사용된다.

AutoConfiguration으로 별다른 설정 없이 Spring Boot에서 바로 Validation을 사용할 수 있다.

Bean Validation Annotation 종류

Validation 어노테이션은 2가지 패키지에 나눠서 존재한다.

  1. jakarta.validation 라이브러리의 javax.validation 패키지
  2. org.hibernate.validator 라이브러리의 org.hibernate.validator.constratins 패키지

javax.validation 패키지에 존재하는 어노테이션

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

애노테이션 설명 지원 타입
@Null null 이어야 한다.
모든 타입 허용
 
@NotNull null을 허용하지 않는다.
" ", ""은 허용한다.
 
@NotEmpty null과 ""를 허용하지 않는다. " "는 허용한다.
collection의 경우 null이 아니고 크기가 0이 아닌지 검사한다.
 
@NotBlank null과 "", " "를 허용하지 않는다.  
@Email 이메일 주소가 유효한지 검사한다.
null은 유효하다고 판단한다.
CharSequence
@Size(min=, max=) 길이 제약조건 검사.
min 이상, max 이하의 길이를 가져야 하며 null은 허용하므로 @NotNull을 같이 사용해야 한다.
CharSequence, Collection, Map, 배열
@Min 길이가 아닌 숫자의 크기를 검사한다.
최소값 검증.
null은 허용하므로 @NotNull을 같이 사용해야 한다.
BigDecimal, BigInteger, byte,
short, int, long
및 관련 Wrapper 타입
@Max 길이가 아닌 숫자의 크기를 검사한다.
최댓값 검증.
null은 허용하므로 @NotNull을 같이 사용해야 한다.
BigDecimal, BigInteger, byte,
short, int, long
및 관련 Wrapper 타입
@AssertTrue ,
@AssertFalse
값이 true인지 또는 false인지 검사한다.
null은 유효하다고 판단한다.
boolean Boolean
@DecimalMax,
@DecimalMin
지정한 값보다 작거나 같은지 또는 크거나 같은지 검사한다.
inclusive가 false면 value로 지정한 값은 포함하지 않는다.
null은 유효하다고 판단한다.
BigDecimal, BigInteger,
CharSequence, byte, short, int, long
및 관련 Wrapper 타입
@Digits 자릿수가 지정한 크기를 넘지 않는지 검사한다.
null은 유효하다고 판단한다.
BigDecimal, BigInteger, CharSequencebyte,
short, int, long
및 관련 Wrapper 타입
@Pattern 값이 정규표현식에 일치하는지 검사한다.
null은 유효하다고 판단한다.
CharSequence
@Positive 양수인지 검사. OrZero가 붙은 것은 0 또는 양수인지 검사한다.
null은 유효하다고 판단한다.
BigDecimal BigInteger
byte, short, int, long
및 관련 Wrapper 타입
@PositiveOrZero 0 또는 양수인지 검사한다.
null은 유효하다고 판단한다.
BigDecimal, BigInteger,
byte, short, int, long, float, double,
및 관련 Wrapper 타입
@Negative 음수인지 검사한다.
null은 유효하다고 판단한다.
BigDecimal BigInteger byte, short, int, long
및 관련 Wrapper 타입
@NegativeOrZero 0 또는 음수인지 검사한다.
null은 유효하다고 판단한다.
BigDecimal BigInteger byte, short, int, long
및 관련 Wrapper 타입
@Future 해당 시간이 미래 시간인지 검사한다.
null은 유효하다고 판단한다.
시간 관련 타입
@FutureOrPresent 현재 또는 미래 시간인지 검사한다.
null은 유효하다고 판단한다.
시간 관련 타입
Date, Calendar, Instant,
LocalDate, LocalDateTime, LocalTime,
MonthDay, OffsetDateTime, OffsetTime,
Year, YearMonth, ZonedDateTime, HijrahDate,
JapaneseDate, MinguoDate, ThaiBuddhistDate
@Past 해당 시간이 과거 시간인지 검사한다.
null은 유효하다고 판단한다.
시간 관련 타입
@PastOrPresent 현재 또는 과거 시간인지 검사한다.
null은 유효하다고 판단한다.
시간 관련 타입


org.hibernate.validator 라이브러리의 org.hibernate.validator.constratins 패키지

애노테이션 설명
@URL(protocol=, host=, port=, regexp=, flags=) 주석이 달린 문자열이 URL인지 확인
매개변수 protocol, host, port는 URL의 해당 부분과 매칭.
추가 정규식은 regexp와 flags를 사용하여 지정할 수 있다.
기본적으로 이 제약 조건에 대한 유효성 검증은 java.net.URL 생성자를 사용하여 문자열의 유효성을 검증.
이는 일치하는 프로토콜 처리기를 사용할 수 있어야 함을 의미.
@UniqueElements 주석이 달린 Collection의 모든 객체가 unique한지 검사
@Range(min=, max=) 주석이 달린 요소의 범위가 min, max 내에 있는지 검사
숫자 값 또는 숫자 값의 문자열 표현에 적용
@Length(min=, max=) 문자열의 길이가 min과 max 사이인지 검사
min의 default 값은 0, max의 default 값은 2147483647
@ISBN(type=) 주석이 달린 CharSequence가 유효한 ISBN인지 검사.
숫자의 길이와 숫자가 모두 확인.
null은 유효한 것으로 간주.
유효성 검사 중에 ISBN 문자가 아닌 것들은 무시된다.
모든 숫자와 X가 유효한 ISBN 문자로 간주된다
이는 숫자를 구분하는 대시가 있는 ISBN을 확인할 때 유용하다. (ex. 978-161-729-045-9)
type은 ISBN의 길이를 정의.
유효한 길이는 10과 13으로 각각 ISBN_10과 ISBN_13으로 표사.
type의 default 값은 ISBN_13.
  • @Length는 Hibernate Validation 어노테이션이며 @Size와 같은 의미이다.
  • @Size가 JPA와 Hinernate로부터 독립적인 bean을 만들어준다. 결과적으로 @Size는 @Length보다 더 가볍다.

@NotNull vs @NonNull vs @Column(nullable=false)

@NotNull@NonNull 둘다 어노테이션 방식이지만 @NonNull은 validator의 validation이 아니라
lombok에서의 entity에 대한 제약조건 검증 어노테이션이다.

값이 null이 들어가면 NullPointException이 일어나며 커스텀 예외로 처리할 수 없다.

값의 null을 처리하고 핸들링 하고 싶다면 @NotNull을 사용하고 혹시나 엔티티에 null이 들어가는 것 자체를 막기 위해서는 @NonNull을 사용하면 될 것 같다.


엔티티 필드에 붙은 @NotNull은 @Valid 어노테이션과 별개로 JPA가 읽어 동작하기 때문에 ConstraintViolaitionExcpeiton이 발생한다.


@Column(nullable=false)는 db에 들어갈 때 null이면 hibernate쪽에서 오류를 발생시키는것.

엔티티 -> column nullable (쿼리실행시 예외처리) /
@NotNull(JPA엔티티 필드값이 null로 채워질 때 예외처리) /
엔티티가 아닌 값은 @Valid(jakarta validation)의 NotNull 또는 lombok의 NonNull