Project/profile-service

Enum Validation

개발자겨려 2025. 5. 1. 13:37
Enum Validation
Enum Validation은 Enum 타입의 데이터가 유효한 값인지 확인하는 과정을 의미한다. 이는 주로 사용자 입력 또는 API 요청에서 Enum 값을 받을 때, 해당 값이 Enum에 정의된 값 중 하나인지 검증하는 데 사용된다.

 

🧩 Enum Validation의 필요성

  • 데이터 무결성 유지: Enum Validation을 통해 유효하지 않은 값이 시스템에 들어오는 것을 방지하여 데이터의 무결성을 유지할 수 있다.
  • 코드 안정성: Enum Validation은 런타임 에러를 줄이고, 코드의 안정성을 높이는 데 기여한다.
  • 가독성 향상: Enum을 사용하면 코드의 가독성이 향상되며, 관련된 상수들을 논리적으로 그룹화할 수 있다.

 

 

🧩 Enum Validation 방법

 

  • Custom Annotation 정의: @interface를 사용하여 Custom Annotation을 정의하고, @Constraint Annotation을 사용하여 유효성 검증 로직을 수행할 Validator 클래스를 지정한다.
//customAnnotation
//package com.profile-service.annotation
//EnumValue.Annotation

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = EnumValidator.class)
public @interface EnumValue {
    Class<? extends Enum<?>> enumClass();
    String message() default "유효하지 않은 Enum 값입니다.";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
    boolean ignoreCase() default false;
}

 

 

  • ConstraintValidator 구현: ConstraintValidator 인터페이스를 구현하여 실제 유효성 검증 로직을 작성한다. initialize() 메서드에서 Annotation의 속성 값을 초기화하고, isValid() 메서드에서 유효성을 검사한다.
//EnumValidator.java
//package com.profile_service
//ConstraintValidator 인터페이스를 구현

public class EnumValidator implements ConstraintValidator<EnumValue, String> {
    private EnumValue enumValue;

    @Override
    public void initialize(final EnumValue constraintAnnotation) {
        this.enumValue = constraintAnnotation;
    }

    @Override
    public boolean isValid(final String value, final ConstraintValidatorContext context) {

        final Enum<?>[] enumConstants = this.enumValue.enumClass().getEnumConstants();
        if (enumConstants == null) {
            return false;
        }

        return Arrays.stream(enumConstants)
                .anyMatch(enumConstant -> convertible(value, enumConstant) || convertibleIgnoreCase(value, enumConstant));
    }

    private boolean convertibleIgnoreCase(final String value, final Enum<?> enumConstant) {
        return this.enumValue.ignoreCase() && value.trim().equalsIgnoreCase(enumConstant.name());
    }

    private boolean convertible(final String value, final Enum<?> enumConstant) {
        return value.trim().equals(enumConstant.name());
    }
}

 

 

  • DTO에서 Annotation 사용: DTO의 필드에 Custom Annotation을 적용하여 유효성을 검사한다.
public class PaymentRequestDto {

    @Enumerated(EnumType.STRING)
    @EnumValue(enumClass = CouponCode.class, message = "유효하지 않은 쿠폰 코드입니다.", ignoreCase = true)
    private String couponCode;  // 쿠폰 코드
    
}

 

 

 

🧩 Enum Validation 시 주의사항

 

  • 대소문자 구분: Enum의 valueOf() 메서드는 대소문자를 구분하므로, 입력 값의 대소문자를 일치시켜야 한다. 필요한 경우 ignoreCase 옵션을 사용하거나, 별도의 로직을 구현하여 대소문자를 무시하도록 처리해야 한다.
  • Null 처리: Enum Validation 시 Null 값에 대한 처리를 고려해야 한다. @NotNull Annotation을 사용하여 Null 값을 허용하지 않거나, isValid() 메서드 내에서 Null 값을 처리하는 로직을 추가할 수 있다.
  • 예외 처리: 유효하지 않은 Enum 값이 입력되었을 때, 적절한 예외를 발생시키고 처리해야 한다. ControllerAdvice 등을 사용하여 예외를 Global하게 처리할 수 있다.