본문 바로가기
Study/SpringBoot

[Spring Boot] @NotNull, @NotEmpty, @NotBlank 의 차이점 및 사용법

by 오늘만 사는 여자 2022. 5. 10.
728x90
반응형

@NotNull, @NotEmpty, @NotBlank 의 차이점

 

앞서 공통적으로 사용하는 방법 및 예외처리에 대해서 알아봤습니다.

@NotNull & @NotEmpty & @NotBlank 는 사용법은 매우 유사하지만 중요한 차이가 있습니다.

 

 

@NotNull

우선 @NotNull 은 위에 살펴본 것 처럼 이름 그대로 Null만 허용하지 않습니다.

따라서, "" 이나 " " 은 허용하게 됩니다.

그렇기 때문에 만약 "" (초기화된 String) )이나 " " (공백) 을 허용하지 않는다면 사용해서는 안됩니다.

Null 이 들어오게 되면, 로직에 예상치 못한 오류가 발생하거나 문제가 생길 경우 사용해야 합니다.

즉, 초기화나 공백의 값이 들어와 저장은 되야하지만 Null 로 들어온 경우 오류가 나는 변수를 받을 때 사용하면 됩니다.

 

@Test
public void 사용자_이름_DTO_NotNull_체크() {
    //given
    UserLoginRequestDto user = UserLoginRequestDto.builder()
                                        .name(null)
                                        .email("")
                                        .phone(" ")
                                        .build();
    //when
    Set<ConstraintViolation<UserLoginRequestDto>> violations = validator.validate(user);

    //then
    assertThat(violations.size()).isEqualTo(1);
}

 

name, email, phone 에 모두 @NotNull 이 걸려있다고 가정했을 때,

위의 테스트를 실행하면 통과를 하게됩니다.

name 은 null 이 들어왔기 때문에 violations 에 검증이 되어 잘못된 값이라 판단하여 추가가 되고, email 같은 경우 ""(empty) 는 null 이 아니기 때문에 violations 에 추가되지 않게 됩니다.

phone 의 경우 " "(blank) 이기 때문에 email 과 마찬가지로 null 이 아니기 때문에 violations 에 추가되지 않습니다.

 

 

@NotEmpty

@NotEmpty  null  "" 둘 다 허용하지 않게 합니다.

@NotNull 에서 "" validation 이 추가된 것입니다.

즉, @NotEmpty  null  "" 은 막히되, " " 은 허용이 됩니다.

@Test
public void 사용자_이름_DTO_NotNull_체크() {
 //given
 UserLoginRequestDto user = UserLoginRequestDto.builder()
                                 .name(null)
                                 .email("")
                                 .phone(" ")
                                 .build();
 //when
 Set<ConstraintViolation<UserLoginRequestDto>> violations = validator.validate(user);

 //then
 assertThat(violations.size()).isEqualTo(2);
}

name, email, phone 에 모두 @NotEmpty 가 걸려있다고 가정했을 때,

위의 테스트를 실행하면 통과를 하게됩니다.

name 은 null 이 들어왔기 때문에 violations 에 검증이 되어 잘못된 값이라 판단하여 추가가 되고, email 같은 경우 ""(empty) 는 ""(empty) 이기 때문에 violations 에 추가가 됩니다.

phone 의 경우 " "(blank) 이기 때문에 null  empty 가 아니기 때문에 violations 에 추가되지 않습니다.

 

 

@NotBlank

@NotBlank  null  ""  " " 모두 허용하지 않습니다.

@NotEmpty 에서 " " validation 이 추가된 것입니다.

즉, 세개 중 가장 validation 강도가 높은 것으로,@NotBlank  null  ""  " " 모두 허용하지 않습니다.

@Test
public void 사용자_이름_DTO_NotNull_체크() {
 //given
 UserLoginRequestDto user = UserLoginRequestDto.builder()
                                 .name(null)
                                 .email("")
                                 .phone(" ")
                                 .build();
 //when
 Set<ConstraintViolation<UserLoginRequestDto>> violations = validator.validate(user);
  //then
 assertThat(violations.size()).isEqualTo(3);
}

name, email, phone 에 모두 @NotBlank 가 걸려있다고 가정했을 때,

위의 테스트를 실행하면 통과를 하게됩니다.

name 은 null 이 들어왔기 때문에 violations 에 검증이 되어 잘못된 값이라 판단하여 추가가 되고, email 같은 경우 ""(empty) 는 ""(empty) 이기 때문에 violations 에 추가가 됩니다.

phone 의 경우 " "(blank) 이기 때문에 violations 에 추가가 되어 총 3개가 violations 에 추가가되어 성공하게 됩니다 .

 

 

 

 

 

결론

앞서 3개의 Bean Validation 의 사용방법, 예외 처리하는 방법, 검증(테스트) 방법에 대해 설명하였습니다.

총 3개의 Validatior 는 사용법과 기능이 유사하기 때문에 쉽게 혼용되거나 잘못 사용될 수 있습니다.

따라서, 해당 DTO 에 대한 테스트를 Validator 에 따라 null , "", " " 에 구분하여 나눠서 추가해야 합니다.

만약, @NotBlank 이어야하는 값이 @NotNull 이 설정되어 공백이 들어오게되면 큰 문제가 발생할 수 있기 때문입니다.

중간에 DTO 를 사용해야하는 이유에 대해서 설명을 드렸습니다.

테스트를 추가할 때도 각 DTO 를 분리하게 되면 각각의 request 에 따라 테스트 코드를 추가해줄 수 있기 때문에 요청을 모두 검증할 수 있어, 테스트 코드에 대한 커버리지가 높아질 수 있습니다.

이처럼 이러한 Validation 을 용도 및 상황에 맞게 사용한다면 사용자의 오류나 시스템의 오류를 최소화 할 수 있습니다.

 

출처 :https://sanghye.tistory.com/36

728x90
반응형

댓글