본문 바로가기
Spring

[Spring] 검증(Bean Validation)

by 당코 2023. 1. 20.

Bean Validation

특정한 구현체가 아니라 Bean Validation 2.0(JSR-380)이라는 기술 표준으로 검증로직을 모든 모든 프로젝트에 적용할 수 있게 공통화하고, 표준화한 것이 바로 Bean Validation이다.

쉽게 말해 검증 애노테이션과 여러 인터페이스의 모음이라고 볼 수 있다.

Bean Validation을 잘 활용하면 애노테이션 하나로 검증 로직을 매우 편리하게 적용할 수 있다

 

Bean Validation 의존관계 추가

Bean Validation을 사용하려면 다음 의존관계를 build.gradle에 추가해야 한다.

//build.gradle

implementation 'org.springframework.boot:spring-boot-starter-validation'

 

검증 애노테이션

  • @AssertTrue, @AssertFalse : 값이 true 또는 false인지 검증한다.
  • @DecimalMax, @DecimalMin : 지정한 값보다 작거나 같은지 또는 크거나 같은지 검사한다.\
  • @Max, @Min : 지정한 값보다 작거나 같은지 또는 크거나 같은지 검사한다.
  • @Digits : 자릿수가 지정한 크기를 넘지 않는지 검사한다.
  • @Size : 길이나 크기가 지정한 값 범위에 있는지 검사한다.
  • @Null, @NotNull : 값이 null인지 또는 null이 아닌지 검사한다.
  • @Pattern : 값이 정규표현식에 일치하는지 검사한다.
  • @NotEmpty :  null이 아니고 길이가 0이 아닌지 검사한다. 
  • @NotBlank : null이 아니고 최소한 한 개 이상의 공백이 아닌 문자를 포함하는지 검사한다.
  • @Positive, @PositiveOrZero : 양수인지 검사하고 OrZero는 0도 포함한다.
  • @Negative , @NegativeOrZero : 음수인지 검사하고 OrZero는 0도 포함한다.
  • @Email : 이메일 주소가 유효한지 검사한다.
  • @Future : 해당 시간이 미래 시간인지 검사한다.
  • @Past : 해당 시간이 과거 시간인지 검사한다.
//사용 예시
public class Item {
 	private Long id;
    
 	@NotBlank
 	private String itemName;
    
 	@NotNull
 	@Range(min = 1000, max = 1000000)
 	private Integer price;
    
 	@NotNull
 	@Max(9999)
 	private Integer quantity;
 //...
}

 

 

검증순서

1. @ModelAttribute 각각의 필드에 타입 변환 시도

  • 성공하면 다음으로
  • 실패하면 typeMismatch로 FieldError 추가

2. Validator 적용

-> 바인딩에 성공한 필드만 Bean Validation 적용한다.

 

에러 코드

오류 코드를 기반으로 MessageCodesResolver를 통해 다양한 메시지 코드가 순서대로 생성된다.

@NotBlank

  • NotBlank.item.itemName
  • NotBlank.itemName
  • NotBlank.java.lang.String
  • NotBlank

@Range

  • Range.item.price
  • Range.price
  • Range.java.lang.Integer
  • Range
메시지 등록
//errors.properties
//Bean Validation 추가
NotBlank={0} 공백X 
Range={0}, {2} ~ {1} 허용
Max={0}, 최대 {1}

 

BeanValidation 메시지 찾는 순서
  1. 생성된 메시지 코드 순서대로 messageSource에서 메시지 찾기
  2. 애노테이션의 message 속성 사용 @NotBlank(message = "공백! {0}")
  3. 라이브러리가 제공하는 기본 값 사용 -> 공백일 수 없습니다.

 

Form 전송 객체 분리

Form에서 전달하는 데이터가 Item 도메인 객체와 딱 맞지 않는 경우가 있다.

회원 등록 시 회원과 관련된 데이터만 전달받는 것이 아니라, 약관 정보도 추가로 받는 등 Item과 관계없는 수많은 부가 데이터가 넘어온다.

보통 Item을 직접 전달받는 것이 아니라, 복잡한 폼의 데이터를 컨트롤러까지 전달할 별도의 객체를 만들어서 전달한다.

폼 데이터 전달에 Item 도메인 객체 사용
HTML Form -> Item -> Controller -> Item -> Repository
폼 데이터 전달을 위한 별도의 객체 사용 
HTML Form -> ItemSaveForm -> Controller -> Item 생성 -> Repository

 

 

출처 : https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-2/dashboard