[Spring] 유효성 검사 시에 UnexpectedTypeException 에러가 발생한다면

Hocaron·2024년 2월 4일
1

Spring

목록 보기
38/44
javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint 'javax.validation.constraints.NotBlank' validating type 'com.xxx.xxx.enums.KeywordType'. Check configuration for 'keywordType'

입력값 검증 시에 @NotBlank 와 같은 유효성 검사를 위한 어노테이션을 많이 사용할 것이다.
enum 같은 경우 null, "", " "(공백이 포함된 문자열)이 모두 유효성 검사에서 통과되지 않도록 @NotBlank 를 사용할 수 있는데, 사용 시에 UnexpectedTypeException 에러가 발생한다.

해당 타입을 validate할 수 있는 validator를 알아보자.

javax.validation.contraints 패키지 내의 유효성 검증 어노테이션

@NotNull

  • 어노테이션은 매개변수가 null인지 아닌지를 검증하는 데 사용된니다. null이 전달되면 예외가 발생하며, 그러나 빈 문자열("")이나 공백이 포함된 문자열(" ")은 null이 아닌 String으로 간주되어 유효성 검사를 통과한다.

  • 적용가능한 타입 : 모든 타입

테스트 케이스

@NotNull
String str1 = null;   // false

@NotNull
String str2 = "";     // true

@NotNull
String str3 = " ";    // true

@NotEmpty

값의 존재 여부를 확인하고, 매개변수가 null이거나 빈 문자열("")인 경우 예외를 발생시킨다. 그러나 문자열에 공백이 포함된 경우(" ") 이는 비어 있지 않은 것으로 간주되어 유효성 검사를 통과한다.

  • 적용가능한 타입 : CharSequence, Collection, Map, Array

  • 테스트 케이스
@NotEmpty
String str1 = null;   // false

@NotEmpty
String str2 = "";    // false

@NotEmpty
String str3 = " ";   // true

@NotBlank

세 가지 중에서 가장 강한 유효성 검사를 제공한다. null, "", " "(공백이 포함된 문자열)을 허용하지 않는다. 이 어노테이션은 문자열에서 전/후 공백을 제거하고 결과적으로 길이가 0보다 큰지 확인한다.

  • 적용가능한 타입 : CharSequence

테스트 케이스

@NotBlank
String str1 = null;   // false

@NotBlank
String str2 = "";    // false

@NotBlank
String str3 = " ";   // false

(번외)만약 inner class 를 validation 하고 싶다면?

public record AddBulkReqDto(

        @NotEmpty
        List<@Valid Content> contents,

        @Valid
        Content content,
        
        @NotNull
        Long id
) {

    public record Content(
            @NotNull
            Long userNo,

            @NotBlank
            String expiredAt
    ) {
    }
}

@Valid를 붙여서 validation 하고 싶은 클래스를 validation 할 수 있다.

(번외) 타입 외에 boolean 메서드 도 체크가 가능하다고

@AssertTrue 어노테이션을 통해 boolean 을 반환하는 메서드 체크도 가능하다. 무슨 말이냐면,

public class Car {

    private LocalDateTime warrantyStartedAt;

    private LocalDateTime warrantyEndedAt;
    
    private boolean isRegistered;
      
    public Car(String manufacturer, boolean isRegistered) {
        super();
        this.manufacturer = manufacturer;
        this.isRegistered = isRegistered;
    }

    @NotNull
    public String getManufacturer() {
        return manufacturer;
    }

    public void setManufacturer(String manufacturer) {
        this.manufacturer = manufacturer;
    }

    @AssertTrue
    public boolean isRegistered() {
        return isRegistered;
    }
    
    @AssertTrue
    public boolean isValidDate() {
        return warrantyStartedAt.isAfter(warrantyEndedAt);
    }
}

정리

  • @NotBlank 는 Strig 타입에 사용가능하다.
  • UnexpectedTypeException 에러 발생 시에는 validator 가 적절한 타입에 쓰였는지 확인하자.

References

profile
기록을 통한 성장을

0개의 댓글