💻본 포스팅은 '스프링 MVC 2편 - 백엔드 웹 개발 활용 기술 - 김영한'님의 강의를 듣고 작성되었습니다.
1. Bean Validation이란?
2. Bean Validation 시작
- 검증 애노테이션
- 검증기 생성
- 검증기 실행
3. Bean Validation - 스프링 적용
- 검증 순서
4. Bean Validation - 에러코드
- FieldError 메시지 코드 우선순위
- BeanValidation 메시지 찾는 순서
5. Bean Validation - 오브젝트 오류
- ObjectError 메시지 코드 우선순위
6. Bean Validation의 한계
[Bean validation이란?]
- 검증 로직을 모든 프로젝트에 적용할 수 있게 공통화하고, 표준화한 것이 Bean Validation이라고 한다.
- Bean Validation은 특정 구현체가 아닌 인터페이스와 애노테이션의 모음인 셈이다.
- JPA를 표준 기술로 그 기술을 구현하는 구현체에 하이버네이트가 있는 것과 같다.
- Bean Validation을 구현하는 구현체로는(일반적으로 사용하는 구현체) 하이버네이트 Validaitor이고 이름이 하이버네이트가 붙었을 뿐 ORM과는 관계가 없다.
- 구현체를 바꿔낄 수 있다.(오픈 소스에서 구현하거나 상용에서 구현할 수 있다.)
[Bean Validation 시작]
implementation 'org.springframework.boot:spring-boot-starter-validation'
- 의존관계를 주입시켜 주어야 사용할 수 있다.
- 자동으로 라이브러리를 spring이 추가해준다.
- javax validation(인터페이스)을 추가해준다.
- 하이버네이트 validator(구현체)도 추가해준다.(대다수의 기업이 하이버네이트 validator을 사용한다.)
package hello.itemservice.domain.item;
import lombok.Data;
import org.hibernate.validator.constraints.Range;
import javax.validation.constraints.Max;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Data
public class Item {
private Long id;
@NotBlank(message = "공백 X")
private String itemName;
@NotNull
@Range(min = 1000, max = 1000000)
private Integer price;
@NotNull
@Max(9999)
private Integer quantity;
public Item() {
}
public Item(String itemName, Integer price, Integer quantity) {
this.itemName = itemName;
this.price = price;
this.quantity = quantity;
}
}
[검증 애노테이션]
- @NotBlank : 빈값 + 공백만 있는 경우를 허용하지 않는다.
- @NotNull : null 을 허용하지 않는다.
- @Range(min = 1000, max = 1000000) : 범위 안의 값이어야 한다.
- 하이버네이트 validator 구현체 사용에만 사용할 수 있다.
- @Max(9999) : 최대 9999까지만 허용한다.
[검증기 생성]
- 스프링과 통합하면 우리가 직접 검증기 생성 코드를 작성하지 않음
[검증기 실행]
- 검증 대상을 직접 검증기에 넣고 그 결과를 받는다.
- Set에는 ConstraintViolation이라는 검증 오류가 담긴다.
- 따라서 결과가 비어있으면 검증 오류가 없는 것이다.
Set<ConstraintViolation<Item>> violations = validator.validate(item);
[Bean Validation - 스프링 적용]
- 우리가 직접 만든 검증 class를 뺏을 때도 Bean Validation 애노테이션 검증이 제대로 작동하는 이유?
- 스프링부트에 라이브러리를 추가해주어서 스프링부트가 자동으로 Bean Validator를 작동시켜준다.
- 스프링부트는 global validator로 적용해서 NotNull과 같은 경우를 다 찾아서 검증해준다.
[검증 순서]
- @ModelAttribute 바인딩
- 성공하면 다음으로
- 실패하면 typeMismath로 FieldError 추가
- Bean Validator 적용
- 타입 변환에 성공한 경우만 적용 된다.
[Bean Validation - 에러코드]
NotBlank라는 오류 코드를 기반으로 MessageCodesResolver를 통해 다양한 메시지 코드가 순서대로 생성된다.
[Error 메시지 코드 우선순위]
@NotBlank
- NotBlank.item.itemName
- NotBlank.itemName
- NotBlank.java.lang.String
- NotBlank
@Range
- Range.item.price
- Range.price
- Range.java.lang.Integer
- Range
[BeanValidation 메시지 찾는 순서]
[BeanValidation 메시지 찾는 순서]
1. 생성된 메시지 코드 순서대로 messageSource 에서 메시지 찾기
2. 애노테이션의 message 속성 사용 @NotBlank(message = "공백! {0}")
3. 라이브러리가 제공하는 기본 값 사용 공백일 수 없습니다.
[Bean Validation - 오브젝트 오류]
- FieldError가 아닌 ObjectError는 어떻게 처리를 할까?
- @ScriptAssert( )를 사용하면 된다.
@ScriptAssert(lang = "javascript", script = "_this.price * _this.quantity >= 10000")
[메시지 코드 우선순위]
- ScriptAssert.item
- ScriptAssert
강사님 주관적인 의견으로 필드 관련 에러는 Bean Validation 사용하고 Object 관련 에러는 자바 코드로 작성하는 것을 권장한다고 한다.
[Bean Validation의 한계]
- 요구 사항 변경이 요청될 경우 상충하는 요구 사항이 충돌할 수 있어서 이를 계속 검증해야 한다.
- 즉 동일 모델 객체를 등록할 때와 수정할 때 각각 다르게 검증하는 방법을 알아보아야 한다.
- (다음 포스팅에서 계속...)
'Back-End > Spring' 카테고리의 다른 글
[Spring MVC2][검증2(Validation)] - Form 전송 객체 분리 (0) | 2022.05.05 |
---|---|
[Spring MVC2][검증2(Validation)] - Bean Validation - groups (0) | 2022.05.03 |
[Spring MVC2][검증(Validation)] - 컨트롤러와 검증의 분리 (0) | 2022.05.02 |
[Spring MVC2][검증(Validation)] - 오류 코드와 메시지 처리 (0) | 2022.04.27 |
[Spring MVC2][검증(Validation)] - FieldError, ObjectError(부제: 사용자 입력 오류에도 입력해 놓은 데이터를 그대로 유지해보자) (0) | 2022.04.27 |