본문 바로가기

Spring Framework

DTO Validation 커스터마이징하기 (List 리스트 길이 제한)

반응형

스프링 프레임워크 첫글은 간단한 어노테이션 커스터마이징 부터 시작하겠다.

Dto 변수 중에

List<Object> 형태의 변수가 있는데, 이것의 list 길이의 갯수를 validate하고 싶을 때는 커스터마이징한 어노테이션으로 간단하게 해결가능하다.

public class CreateProjectRewardDto {

  @Valid
  @IsValidListSize(min = 0, max = 100)
  private List<ProjectItemDto> items = new ArrayList<>();
}

@IsValidListSize 라는 List의 길이를 제한하는 어노테이션을 새롭게 만들어볼 것이다.

아래는 @IsValidListSize 어노테이션 코드

@Documented
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = ListSizeValidator.class)
public @interface IsValidListSize {
  String message() default "";

  int max() default 100;

  int min() default 0;

  Class<?>[] groups() default {};

  Class<? extends Payload>[] payload() default {};
}

위의 ListSizeValidator.class 에서 실제로, validate가 boolean 으로 이루어진다.

  • min, max 라는 어노테이션 내 파라미터를 정의해준다.
  • @Target은 어노테이션을 선언할 수 있는 타입을 정의한다. 예로들면, 저기서는 ElementType 이 필드인 경우에 어노테이션을 선언할 수 있다.
  • @Retention은 어노테이션의 작동 범위를 정의한다. RUNTIME 동안 어노테이션이 작동하게 설정을 해뒀다.

아래는 ListSizeValidator 클래스 코드

@Component
public class ListSizeValidator implements ConstraintValidator<IsValidListSize, List<?>> {

  private int maxSize;
  private int minSize;

  @Override
  public boolean isValid(List<?> itemList, ConstraintValidatorContext cxt) {
    if (itemList.size() <= maxSize && itemList.size() >= minSize) {
      return true;
    } else {
      cxt.disableDefaultConstraintViolation();
      cxt.buildConstraintViolationWithTemplate(
              String.format("리스트 원소의 갯수는 최소 %s, 최대 %s 개 입니다.", minSize, maxSize))
          .addConstraintViolation();
      return false;
    }
  }

  @Override
  public void initialize(IsValidListSize constraintAnnotation) {
    this.maxSize = constraintAnnotation.max();
    this.minSize = constraintAnnotation.min();
  }
}

ListSizeValidator는 ConstraintValidator를 구현하고 있다.

ConstarintValidator는 어노테이션과, 우리가 판별한 오브젝트 두 가지를 받아서 구현한다. 여기서는 어떤 Object의 List라도 구현될 수 있도록 와일드 카드로 구현하였다.

반응형