SWM-99-degree / jariBean

SWM 14th JariBean Project
0 stars 1 forks source link

[REFACTOR] AOP를 이용한 Request Body의 startTime, endTime 필드의 유효성 검사 #228

Closed isayaksh closed 1 year ago

isayaksh commented 1 year ago

✏️ Description

클라이언트에서 예약을 진행할 때 예약 내역을 저장하기 위해 {server}/api/reserve에 요청을 보낼 때 Request Body의 DTO에 시작 시간(startTime) 종료 시간(endTime)에 대한 필드가 존재한다. 기본적으로 종료 시간은 시작 시간보다 빠를 수 없다.

잘못된 요청 방식

image

테스트 결과 요청을 보낼 경우 종료 시간이 시작 시간보다 빨라도 저장이 되는 문제가 발생하였다. 해당 문제를 해결하기 위해서는 DTO에 시작 시간(startTime) 종료 시간(endTime)에 대한 필드가 존재할 경우 검증 로직을 거쳐 검증에 통과할 경우에만 해당 기능이 수행될 수 있도록 수정해야 한다.

모든 Controller에 DTO에 대한 검증 코드를 추가하는 것은 이후 수정이나 새로운 Controller가 발생할 경우 추가적인 작업이 많아질 수 있기 때문에 Spring에서 제공하는 AOP 기능을 활용하여 문제를 해결한다.

🔥 Solution

ConstraintValidator를 이용하여 예외처리 작업을 처리하였다.

CustomValidator

public class CustomValidator implements ConstraintValidator<CustomConstraint, TimeDto> {

    @Override
    public void initialize(CustomConstraint constraintAnnotation) {
        // 초기화 로직 (필요한 경우)
    }

    @Override
    public boolean isValid(TimeDto timeDto, ConstraintValidatorContext context) {

        LocalDateTime now = LocalDateTime.now();
        LocalDateTime startTime = timeDto.getStartTime();
        LocalDateTime endTime = timeDto.getEndTime();

        if(now.isAfter(startTime) || now.isAfter(endTime)) {
            return false;
        }

        if(startTime.isAfter(endTime)) {
            return false;
        }

        if (!(startTime.getMinute() == 0 || startTime.getMinute() == 30) ||!(endTime.getMinute() == 0 || endTime.getMinute() == 30)) {
            return false;
        }

        return true;
    }
}

CustomConstraint

@Target({ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = CustomValidator.class)
public @interface CustomConstraint {
    String message() default "Custom validation error message";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}