Validation이란?
- 유효성 검증
- 주로 사용자 또는 타 서버의 요청 내용에 잘못된 내용이 있는지 확인하는 행위를 의미
Validation 종류
- 데이터 검증
- 필수 데이터의 존재 유무
- 문자열의 길이나 숫자형 데이터의 값의 범위
- email, 신용카드 번호 등 특정 형식에 맞춘 데이터
- 비즈니스 검증
- 서비스 정책에 따라 데이터를 확인하여 검증
- 경우에 따라 외부 API를 호출하거나 DB의 데이터까지 조회하여 검증하는 경우도 존재
Spring의 Validation
- 스프링은 웹 레이어에 종속적이지 않은 방법으로 검증을 하려고 의도하고 있으며 주로 두가지 방법을 활용하여 검증을 진행한다.
Java Bean Validation
- Java Bean 기반으로 개별 데이터를 검증
- 가장 많이 활용되는 방법 중 하나
- Java Bean 내에 어노테이션으로 검증 방법을 표시
- 설정 파일에 @EnableWebMvc 를 추가해야한다. (스프링 부트는 기본)
public class RegisterRequest {
@NotBlank(message="이름을 입력해주세요.")
@Size(max=64, message="이름의 최대 길이는 64자 입니다.")
private String name;
@Min(0, "나이는 0보다 커야 합니다.")
private int age;
@NotBlank
@Email("이메일 형식이 잘못되었습니다.")
private int email;
// the usual getters and setters...
}
@PostMapping(value = "/register")
public String regist(@Valid RegisterRequest registerRequest,Errors errors) {
// 검증 에러가 발생했다면 Errors를 통해 다양한 처리를 할 수 있다.
if(errors.hasErrors()) return "register/error";
// 코드 작성
}
- 기본 에러 메시지 대신 원하는 에러 메시지를 사용하려면 규칙을 지켜 메시지 프로퍼티 파일에 추가
- 애노테이션 이름.객체모델명.프로퍼티명
- 애노테이션 이름.프로퍼티명
- 애노테이션 이름
- Java Bean Validation 주요 애노테이션 - (2) 표시는 Bean Validation 2.0 제공
애노테이션 | 주요 속성 | 설명 | 지원 타입 |
@AssertTrue @AssertFalse |
값이 true인지 또는 false인지 검사한다. null은 유효하다고 판단한다. | boolean Boolean |
|
@DecimalMax @DecimalMin |
String value - 최댓값 또는 최솟값 boolean inclusive - 지정값 포함 여부 - 기본 값 true |
지정한 값보다 작거나 같은지 또는 크거나 같은지 검사한다. inclusive가 false면 value로 지정한 값은 포함하지 않는다. null은 유효하다고 판단한다. |
BigDecimal BigInteger CharSequence byte, short, int, long 및 각 래퍼 타입 |
@Max @Min |
long value | 지정한 값보다 작거나 같은지 또는 크거나 같은지 검사한다. null은 유효하다고 판단한다. |
BigDecimal BigInteger byte, short, int, long 및 관련 래퍼 타입 |
@Digits | int integer - 허용 가능한 정수 자릿수 int fraction - 허용 가능한 소수점 이하 자릿수 |
자릿수가 지정한 크기를 넘지 않는지 검사한다. null은 유효하다고 판단한다. |
BigDecimal BigInteger CharSequence byte, short, int, long 및 관련 래퍼 타입 |
@Size | int min - 최소 크기 - 기본 값 0 int max - 최대 크기 - 기본 값 |
길이나 크기가 지정한 값 범위에 있는지 검사한다. null은 유효하다고 판단한다. |
CharSequence Collection Map 배열 |
@Null @NotNull |
값이 null인지 또는 null이 아닌지 검사한다. | ||
@Pattern | String regexp - 정규표현식 |
값이 정규표현식에 일치하는지 검사한다. null은 유효하다고 판단한다. |
CharSequence |
@NotEmpty (2) | 문자열나 배열의 경우 null이 아니고 길이가 0이 아닌지 검사한다. 콜렉션의 경우 null이 아니고 크기가 0이 아닌지 검사한다. |
CharSequence Collection Map 배열 |
|
@NotBlank (2) | null이 아니고 최소한 한 개 이상의 공백아닌 문자를 포함하는지 검사한다. | CharSequence | |
@Positive (2) @PositiveOrZero (2) |
양수인지 검사한다. OrZero가 붙은 것은 0 또는 양수인지 검사한다. null은 유효하다고 판단한다. |
BigDecimal BigInteger byte, short, int, long 및 관련 래퍼 타입 |
|
@Negative (2) @NegativeOrZero (2) |
음수인지 검사한다. OrZero가 붙은 것은 0 또는 음수인지 검사한다. null은 유효하다고 판단한다. |
BigDecimal BigInteger byte, short, int, long 및 관련 래퍼 타입 |
|
@Email (2) | 이메일 주소가 유효한지 검사한다. null은 유효하다고 판단한다. |
CharSequence | |
@Future (2) @FutureOrPresent (2) |
해당 시간이 미래 시간인지 검사한다. OrPresent가 붙은 것은 현재 또는 미래 시간인지 검사한다. null은 유효하다고 판단한다. |
시간 관련 타입 | |
@Past (2) @PastOrPresent (2) |
해당 시간이 과거 시간인지 검사한다. OrPresent가 붙은 것은 현재 또는 과거 시간인지 검사한다. null은 유효하다고 판단한다. |
시간 관련 타입 |
Spring Validator 인터페이스 구현을 통한 Validation
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");
}
}
}
- supports()
- validator가 동작할 조건을 정의하며 주로 class 타입을 비교한다.
- validate()
- 검증 로직을 작성한다.
Validation 수행 시 주의사항 및 패턴
- 주의사항
- validation이 너무 여러 곳에 흩어져있으면 테스트 및 유지보수성 저하
- 중복된 검증 : 정책 변경 시 모든 중복 코드를 수정해야 함
- 다른 검증 : 여러 곳에서 다른 정책을 따르는 검증이 수행될 수 있음
- 가능한 validation은 로직 초기에 수행 후 실패 시에는 exception을 던지는 편이 처리가 편함
- validation이 너무 여러 곳에 흩어져있으면 테스트 및 유지보수성 저하
- 실무 활용 패턴
- 요청 dto에서 Java Bean Validation으로 단순 데이터를 1차 검증
- 로직 초기에 2차로 비즈니스 검증 수행 후, 실패 시에는 Custom Exception(ErrorCode, ErrorMessage)을 입력해서 예외를 던지도록 하고 예외처리하여 응답 생성
- Spring Validator의 장단점
- 장점
- Java Bean Validation에 비해 조금 더 복잡한 검증이 가능
- 단점
- Validation을 수행하는 코드를 찾기가 어렵다
- 완전히 데이터만 검증하느 넛이 아니기 때문에 일부 비즈니스적인 검증이 들어가는 경우가 생긴다. 이런 경우 비즈니스 검증 로직이 여러 군데로 흩어지기 때문에 잘못된 검증을 수행할 가능성이 높아진다.
- 장점
- 프로젝트 팀이 선택하는 검증 패턴을 따르는 것이 좋다.
'Spring Framework > Spring' 카테고리의 다른 글
스프링 MVC - HTTP Request,Response (0) | 2022.06.08 |
---|---|
스프링 MVC - 전체 구조 (0) | 2022.06.08 |
Data Binding (0) | 2022.06.07 |
Spring AOP(관점 지향 프로그래밍) (0) | 2022.06.07 |
DI 정리 (0) | 2022.06.06 |
댓글