[Java, Spring]Validation

김우진·2022년 5월 3일
0

Spring & Spring Boot

목록 보기
7/9

Validation

Java에서는 null 값에 대해서 접근 하려할 때, null pointer exception이 발생하는 것과 같이 여러 오류가 여러 상황에서 발생하는 데, 이러한 부분을 방지 하기 위해 미리 검증 하는 과정을 validation이라 한다.

validation은 어려운 것이 아니라 아래 코드와 같이 한 번 쯤 작성 해봤을 코드들이다.

public void run(String account, String pw, int age) {
	if(account == null || pw == null)
   		return;
    if(age == 0) 
    	return;
        
    // 정상 Logic

하지만, 위와 같은 코드는 parameter의 갯수가 적기 때문에 코드가 적지만, parameter가 객체가 들어오거나해서 갯수가 들어나면 그만큼 코드의 길이가 길어진다. 또한, 코드가 짧더라도 가능하면 Service Logic과 Validation Logic은 분리 되는 것이 함수의 역할이 눈에 보기 좋다.

Spring에서는 이러한 Validation Code를 모아서 관리하며 Validation과 관련된 annotation(@Valid,@Size, etc...)을 제공한다.

Custom Validation

Spring에선 기존에 주어지는 Validation외에 사용자가 직접 만들어서 검증을 할 수 있는 방식을 제공한다.

AssertTrue

AssertTrue는 Method에 @AssertTure를 붙이고 그 Method가 true를 return했을 땐 validation 성공, false를 return 했을 땐 validation 실패를 알리는 annotation이다.

@AssertTrue(message = "yyyyMM"의 형식에 맞지 않습니다.
public boolean isReqYearMothValidation() {
    try {
    	LocalDate localDate = LocalDate.parse(getReqYearMonth() + "01", DateTimeFormatter.ofPattern("yyyyMMDD"));
    } catch (Exception e) {
    	return false;
    }
    return true;
}

한 가지 유의해야할 때 이 @AssertTrue를 사용하는 Method의 Name은 is로 시작해야한다.

Custom Valid Annotation

위의 방식으로 직접 validation을 진행 할 수 있지만, 이러한 로직이 필요한 곳이 많은 서비스인 경우 반복되는 코드가 무수히 많아 질 것이다. 이 경우, @AssertTrue로 Method 하나하나를 만드는 것 보단, 직접 Valid Annotation을 만드는 것이 좋다.

@Constraint(validationBy = { YearMonthValidator.class })	// 어떤 Class로 다룰 것이냐
@Target({ MEHTOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })	// 어디에 붙일 것이냐
@Retention(RUNTIME)
public @interface YearMonth {

	String message() default "yyyyMM의 형식에 맞지 않습니다.";
    
    Class<?>[] groups() default { };
    
    Class<? extends Payload>[] payload() default { };
}

	String pattern() default "yyyyMMdd";
@YearMonth
private String reqYearMonth;
public class YearMonthValidator implements ConstraintValidator<YearMonth, String> {
	private String pattern;
    
    @Override
    public void initialize(YearMonth constraintAnnotation) {
    	this.pattern = constraintAnnotation.pattern();
    }
    
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
    	try {
    	LocalDate localDate = LocalDate.parse(value+"01", DateTimeFormatter.ofPattern(this.pattern));
    } catch (Exception e) {
    	return false;
    }
        
        return true;
    }
}

위와같이 Validation Annotation을 만들고 그것을 다둘 Class를 만들어 연결해주면 Custom Validation Annotation 사용할 수 있다.

0개의 댓글