본문 바로가기
Spring

Custom Validation 사용해보기

by Heesu.lee 2021. 3. 20.

실제 애플리케이션을 개발하다 보면 어떤 객체의 값이 비었는지, 공백인지, 재대로 된 패턴에 맞는지 등의 유효성 검사를 빈번하게 사용해야 하는 경우가 많습니다.

 

Spring 에서는 Java Bean Validation 을 이용하여 검사 대상 클래스에 어노테이션 기반 제약 조건을 선언하여 간결하게 유효성 검사를 할 수 있습니다. 

 

의존성

...

dependencies {

    ...
	
    implementation("org.springframework.boot:spring-boot-starter-validation")
	
    ...
}

...

 

spring-starter-validation 의존성을 추가하여 사용

 

사용 예시

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class AccountDto {

    @Builder
    @Getter @Setter
    @AllArgsConstructor
    @NoArgsConstructor
    public static class Save {

        @NotNull
        private Long accountNumber;

        @NotNull
        private Long balance;

        @NotBlank
        private String firstname;

        @NotBlank
        private String lastname;

        private int age;

        @NotBlank
        private String gender;

        @NotBlank
        private String address;

        @NotBlank
        private String employer;

        @NotBlank
        private String email;

        @NotBlank
        private String city;

        @NotBlank
        private String state;
    }
 
    ...
 
 }

받아온 데이터가 null, 공백 여부 등의 유효성을 검사

NotNull 은 단순히 Null 여부만 판단하지만, NotBlank 의 경우 Null 체크 뿐만 아니라 빈 문자열, 공백인지도 검사한다.

이외에도 주어진 패턴에 부합하지를 확인해주는 Pattern 과 true 혹은 false 등의 Boolean 값을 판단해주는 AssertTrue, AssertFalse 등 다양한 유효성 검사 어노테이션이 존재한다.

 

더 다양한 Validation 에 대한 사용은 다음 아래 블로그에서 확인할 수 있다. - 링크

 

Validation 어디까지 해봤니? : NHN Cloud Meetup

TOAST Cloud의 메시징 플랫폼 상품인 Notification은 메시지, 이메일 주소 형식, 수신/발신자의 번호 등 클라이언트의 입력값에 대해 많은 검증을 진행합니다.

meetup.toast.com

 

그렇지만, 기본적으로 제공하는 유효성 검사 말고도 비즈니스 로직에 맞추어 새롭게 유효성 검사 로직을 정의해야하는 경우도 있습니다.

이런 경우 직접 Custom 한 어노테이션 및 Validator 를 작성하여 정의해줄 수 있습니다.

Custom Validation

Annotation 생성

@Documented
@Constraint(validatedBy = AccountSearchableFieldValidator.class)
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Searchable {

    String message() default "Not Searchable Field";

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

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

Validator 생성

public class AccountSearchableFieldValidator implements ConstraintValidator<Searchable, String> {

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        return AccountSearchableFields.isSearchableField(value);
    }
}

자신이 정의한 어노테이션에 대한 유효성 검사 로직을 정의하는 클래스 입니다.

ConstraintValidator 인터페이스를 구현해주면서 지정해주는 제네릭 값 첫 번째에는 새롭게 정의한 어노테이션이 들어가고 두 번째 인자로는 정의된 어노테이션이 사용될 필드의 데이터 유형을 작성해줍니다.

 

그리고 유효성 검사 로직을 isValid 메서드를 Override 하여 재정의 해주면 됩니다.

 

사용하기

정의한 어노테이션을 해당 유효성을 검사하고 싶은 필드에 작성하여 사용하면 됩니다.

@Data
public class Search {

    @NotBlank
    @Searchable(message = "검색 가능한 필드가 아닙니다.")
    private String field;

    @NotBlank
    private String content;

    @NotNull
    private Boolean contain;
}
@RequiredArgsConstructor
@RequestMapping("/elastic/accounts")
@RestController
public class AccountApiController {

    private final AccountService accountService;

    @GetMapping("/search")
    public Mono<AccountDto.ResponseList> searchProductAfter(@Valid @RequestBody AccountDto.Search request) {
        return accountService.searchAccounts(request);
    }

}

@Valid 어노테이션을 실제 검사 대상이 되는 DTO 에 작성해주면 해당 데이터를 맵핑할 때 유효성 검사를 진행합니다.

 

'Spring' 카테고리의 다른 글

Spring Data R2DBC 연관관계 구현 - OneToMany  (3) 2021.03.28
Spring Data R2DBC 사용  (0) 2021.03.28
빈 스코프  (0) 2020.12.26
빈 생명주기 콜백  (0) 2020.12.23
Spring 의존관계 자동 주입  (0) 2020.12.21

댓글