본문 바로가기
Spring Framework/Spring

Spring Validation

by 도쿠니 2022. 6. 7.

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을 던지는 편이 처리가 편함
  • 실무 활용 패턴
    • 요청 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

댓글