Validation용 Custom Annotation 만들어보기

murkgom·2023년 2월 7일
0
post-custom-banner

컨트롤러에서 연락처 포맷(000-0000-0000)에 맞는 필드를 받아보자

만들 것들

CellPhoneNumber : Valid용 Annotation
CellPhoneNumberValidator : 실제 검증하는 로직이 있는 Validator
SampleDto : Request에서 연락처를 받을 DTO 클래스

1. Valid용 Annotation 생성

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = CellPhoneNumberValidator.class)
public @interface CellPhoneNumber {
    String message() default "Invalid cellPhone number";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}
  • @Target : Annotation의 사용처
  • @Retention : Annotation의 유지 시간
  • @Constraint : 누가 Validation을 할건지?(CellPhoneNumberValidator 구현 후 기입)

2. Validator 구현

public class CellPhoneNumberValidator implements ConstraintValidator<CellPhoneNumber, String> {

    @Override
    public void initialize(CellPhoneNumber constraintAnnotation) {
        ConstraintValidator.super.initialize(constraintAnnotation);
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (!StringUtils.hasText(value)) {
        	return false;
        }

        Pattern pattern = Pattern.compile("\\d{3}-\\d{4}-\\d{4}");
        Matcher matcher = pattern.matcher(value);
        
        return matcher.matches();
    }
}
  • ConstraintValidator<A, T> : annotation A가 붙은 T값을 검증할 예정입니다.
  • isValid : 실제 검증 로직 구현

3. DTO 구현

@Getter
@Setter
public class SampleDto {
	@CellPhoneNumber
    private String cellPhoneNumber;
}

4. 적용

in SampleController

@GetMapping("/sample")
public void testSampleDto(@Valid SampleDto sampleDto) {
	...
}

in SampleControllerTest

@Test
void testReturnBadRequest() throws Exception {
	mockMvc.perform(get("/sample")
		.param("cellPhoneNumber", "02-111-1241")
	)
	.andDo(print())
	.andExpect(status().isBadRequest());
}

@Test
void testOk() throws Exception {
	mockMvc.perform(get("/sample")
		.param("cellPhoneNumber", "010-1113-1245")
	)
	.andDo(print())
	.andExpect(status().isOk());
}

ref) https://mangkyu.tistory.com/206

post-custom-banner

0개의 댓글