Validation

  • 유효성 검사

  • 사용자 또는 타 서버의 요청(http request) 내용에서 잘못된 내용이 있는지 확인하는 행위


Validation의 종류

  • 데이터 검증
    • 필수 데이터의 존재 유무
    • 문자열의 길이나 숫자형 데이터의 경우 값의 범위
    • email, 신용카드 번호 등 특정 형식에 맞춘 데이터
  • 비즈니스 검증
    • 서비스 정책에 따라 데이터를 확인하여 검증
      • 배달앱인 경우 배달 요청을 할 때 해당 주문건이 결제 완료 상태인지 확인 등
    • 경우에 따라 외부 API를 호출하거나 DB의 데이터까지 조회하여 검증하는 경우도 존재


Spring의 Validation

  • 스프링은 웹 레이어에 종속적이지 않은 방법으로 밸리데이션을 하려고 의도하고 있다
  • 주로 아 래 두가지 방법을 활용하여 밸리데이션 진행(둘다 데이터 검증에 가까움)


1. Java Bean Validation

  • JavaBean 기반으로 간편하게 개별 데이터를 검증
  • 요즘에 가장 많이 활용되는 방법 중 하나이며, JavaBean 내에 어노테이션으로 검증방법을 명시함
1
2
3
4
5
6
7
8
9
10
11
public class MemberCreationRequest {
    @NotBlank(message="이름을 입력해주세요.")
    @Size(max=64, message="이름의 최대 길이는 64자 입니다.")
    private String name;
    @Min(0, "나이는 0보다 커야 합니다.")
    private int age;
    @Email("이메일 형식이 잘못되었습니다.")
    private int email;
    
    // the usual getters and setters...
}

위처럼 요청 dto에 어노테이션으로 명시 후 아래처럼 @Valid 어노테이션을 해당 @RequestBody에 달게 되면, Java Bean Validation을 수행한 후 문제가 없을 때만 메서드 내 부로 진입이 된다.

  • 검증 중 실패가 발생하면? : MethodArgumentNotValidException이 발생
1
2
3
4
5
@PostMapping(value = "/member")
public MemeberCreationResponse createMember(
    @Valid @RequestBody final MemeberCreationRequest memeberCreationRequest) {
    // member creation logics here...
}


2. Spring validator 인터페이스 구현을 통한 validation

  • supports(): 이 validator가 동작할 조건을 정의, 주로 class의 타입을 비교
  • validate(): 원하는 검증을 진행한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Person {
    private String name;
    private int age;
    // the usual getters and setters...
}

public class PersonValidator implements Validator {
    /**
    * This Validator validates only Person instances
    */
    public boolean supports(Class clazz) {
        return Person.class.equals(clazz);
    }
    
    public void validate(Object obj, Errors e) {
        ValidationUtils.rejectIfEmpty(e, "name", "name.empty");
        Person p = (Person) obj;
        if (p.getAge() < 0) {
            e.rejectValue("age", "negativevalue");
        } else if (p.getAge() > 110) {
            e.rejectValue("age", "too.darn.old");
        }
    }
}


Data Binding

  • 사용자나 외부 서버의 요청 데이터를 특정 도메인 객체에 저장해서 우리 프로그램에 Request에 담아주는 것


Converter<S,T> Interface

  • S(Source)라는 타입을 받아서 T(Target)이라는 타입으로 변환해주는 Interface
1
2
3
4
5
package org.springframework.core.convert.converter;

public interface Converter<S, T> {
    T convert(S source);
}


Formatter

  • 특정 객체와 String 간의 변환을 담당
  • Formatter도 Converter와 마찬가지로 Spring Bean으로 등록하면 자동으로 ConversionService에 등록시켜주기 때문에 필요(요청/응답 시 해당 데이터 타입이 있는 경우) 에 따라 자동으로 동작하게 된다.
  • Formatter예제
    • print: API 요청에 대한 응답을 줄 때, Date형식으로 된 데이터를 특정 locale에 맞춘 String으로 변환
    • parse: API 요청을 받아올 때, String으로 된 “2021-01-01 13:15:00” 같은 날짜 형식의 데 이터를 Date로 변환하도록 함
1
2
3
4
5
6
7
8
9
10
11
12
13
package org.springframework.format.datetime;

@Component
public final class DateFormatter implements Formatter<Date> {
    public String print(Date date, Locale locale) {
        return getDateFormat(locale).format(date);
	}
    
    public Date parse(String formatted, Locale locale) throws ParseException {
        return getDateFormat(locale).parse(formatted);
    }
    // getDateFormat 등 일부 구현은 핵심에 집중하기 위해 생략...
}

카테고리:

업데이트:

댓글남기기