Bean Validation 이란?
-> Bean Validation은 특정한 구현체가 아니라 Bean Validation 2.0이라는 기술 표준이다. 쉽게 이야기해서 검증 에노테이션과 여러 인터페이스의 모음이다. 마치 JPA가 표준 기술이고 그 구현체로 하이버네이트가 있는 것과 같다.
Bean Validation을 구현한 기술중에 일반적으로 사용하는 구현체는 하이버네이트 Validator이다. 이름이 하이버네이트가 붙어서 그렇지 ORM과는 관련이 없다.
Bean Validation 의존관계 추가
Bean Validation을 사용하려면 다음 의존관계를 추가해야 한다.
build.gradle에서!
implementation 'org.springframework.boot:spring-boot-starter-validation'
검증 애노테이션@NotBlank : 빈값 + 공백만 있는 경우를 허용하지 않는다.@NotNull : null 을 허용하지 않는다.@Range(min = 1000, max = 1000000) : 범위 안의 값이어야 한다. @Max(9999) : 최대 9999까지만 허용한다.
스프링 MVC는 어떻게 Bean Validator를 사용할까?
- 스프링 부트가 'spring-boot-starter-validation' 라이브러리를 넣으면 자동으로 Bean Validator를 인지하고 스프링에 통합한다.
- 스프링부트는 자동으로 글로벌 Validator로 등록한다.
- 'LocalValidatorFactoryBean'을 글로벌 Validator로 등록한다. 이 Validator는 @NotNull같은 애노테이션을 보고 검증을 수행한다.
- 이렇게 글로벌 Validator가 적용되어 있기 때문에, @Valid, @Validated만 적용하면 된다.
- 검증 오류가 발생하면, FieldError, ObjectError를 생성해서 BindingResult에 담아준다.
import lombok.Data;
import org.hibernate.validator.constraints.Range;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Data
public class ItemUpdateForm {
@NotNull
private Long id;
@NotBlank
private String itemName;
@NotNull
@Range(min = 1000, max = 1000000)
private Integer price;
//수정에서는 수량은 자유롭게 변경할 수 있다. private Integer quantity;
}
// view
@PostMapping("/add")
public String addItem(@Validated @ModelAttribute("item") ItemSaveForm form,
BindingResult bindingResult, RedirectAttributes redirectAttributes) {
//특정 필드 예외가 아닌 전체 예외
if (form.getPrice() != null && form.getQuantity() != null) {
int resultPrice = form.getPrice() * form.getQuantity();
if (resultPrice < 10000) {
bindingResult.reject("totalPriceMin", new Object[]{10000,
resultPrice}, null);
} }
주의
@ModelAttribute("item")에 item이름을 넣어준 부분을 주의!!
이것을 넣지않으면 ItemSaveForm의 경우 규칙에 의해 itemSaveForm이라는 이름으로 MVC Model에 담기게 된다. 이렇게 되면 뷰 템플릿에서 접근하는 object이름도 함께 변경 해주어야 한다.
@ModelAttribute vs @RequestBody
HTTP 요청 파리미터를 처리하는 @ModelAttribute 는 각각의 필드 단위로 세밀하게 적용된다. 그래서 특정 필드 에 타입이 맞지 않는 오류가 발생해도 나머지 필드는 정상 처리할 수 있었다.HttpMessageConverter 는 @ModelAttribute 와 다르게 각각의 필드 단위로 적용되는 것이 아니라, 전체 객체 단위로 적용된다.
따라서 메시지 컨버터의 작동이 성공해서 ItemSaveForm 객체를 만들어야 @Valid , @Validated 가 적용된다.@ModelAttribute 는 필드 단위로 정교하게 바인딩이 적용된다. 특정 필드가 바인딩 되지 않아도 나머지 필드 는 정상 바인딩 되고, Validator를 사용한 검증도 적용할 수 있다.@RequestBody 는 HttpMessageConverter 단계에서 JSON 데이터를 객체로 변경하지 못하면 이후 단계 자 체가 진행되지 않고 예외가 발생한다. 컨트롤러도 호출되지 않고, Validator도 적용할 수 없다.
'Spring & SpringBoot' 카테고리의 다른 글
| Spring이용하여 File 업로드 하기 및 File Download(2) (0) | 2023.12.03 |
|---|---|
| Spring이용하여 File 업로드 하기 및 File Download(1) (0) | 2023.12.03 |
| 스프링 빈의 Life Cycle (1) | 2023.12.02 |
| 스프링 싱글톤 패턴 (1) | 2023.12.02 |
| Spring IoC, DI, 그리고 컨테이너 (0) | 2023.12.02 |