Bean Validation
- Bean Validation은 특정한 구현체가 아닌 Bean Validation 2.0(JSR-380)이라는 기술 표준이다.
- 검증 애노테이션과 여러 인터페이스의 모음이다.
스프링 MVC에서 Bean Validator 사용하는 방법
스프링 부트가 spring-boot-starter-validation 라이브러리를 넣으면 자동으로 Bean Validator를 인지하고 스프링에 통합한다.
implementation 'org.springframework.boot:spring-boot-starter-validation'
Bean Validation 애노테이션 적용 코드
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
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): 범위 안의 값이어야 한다.
- @Max(9999): 최대 9999까지만 허용한다.
Bean Validation - groups
동일한 모델 객체를 등록할 때와 수정할 때 각각 다르게 검증하는 방법이다.
저장용 groups 생성
package hello.itemservice.domain.item;
public interface SaveCheck {
}
수정용 groups 생성
package hello.itemservice.domain.item;
public interface UpdateCheck {
}
Item - groups 적용
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 {
@NotNull(groups = UpdateCheck.class) //수정시에만 적용
private Long id;
@NotBlank(groups = {SaveCheck.class, UpdateCheck.class})
private String itemName;
@NotNull(groups = {SaveCheck.class, UpdateCheck.class})
@Range(min = 1000, max = 1000000, groups = {SaveCheck.class, UpdateCheck.class})
private Integer price;
@NotNull(groups = {SaveCheck.class, UpdateCheck.class})
@Max(value = 9999, groups = SaveCheck.class) //등록시에만 적용
private Integer quantity;
public Item() {
}
public Item(String itemName, Integer price, Integer quantity) {
this.itemName = itemName;
this.price = price;
this.quantity = quantity;
}
}
groups 기능은 실제 잘 사용되지 않는다. 실무에서는 주로 등록용 폼 객체와 수정용 폼 객체를 분리해서 사용하기 때문이다.
Form 전송 객체 분리
- 실무에서는 groups를 잘 사용하지 않는다. 등록시 폼에서 전달하는 데이터가 Item 도메인 객체와 딱 맞지 않기 때문이다.
- 그래서 보통 Item을 직접 전달받는 것이 아니라, 복잡한 폼 데이터를 컨트롤러까지 전달할 객체를 만들어서 전달한다.
폼 데이터 전달에 Item 도메인 객체 사용
HTML Form → Item → Controller → Item → Repository
- 장점: Item 도메인 객체를 컨트롤러, 레포지토리까지 직접 전달해서 중간에 Item을 만드는 과정이 없어 간단하다.
- 단점: 간단한 경우에만 적용할 수 있다. 수정 시 검증이 중복될 수 있고 groups를 사용해야 한다.
폼 데이터 전달을 위한 별도의 객체 사용
HTML Form → ItemSaveForm → Controller → Item 생성 → Repository
- 장점: 전송하는 폼 데이터가 복잡해도 거기에 맞춘 별도의 폼 객체를 사용해서 데이터를 전달 받을 수 있다. 보통 등록과 수정용으로 별도의 폼 객체를 만들기 때문에 검증이 중복되지 않는다.
- 단점: 폼 데이터를 기반으로 컨트롤러에서 Item 객체를 생성하는 변환 과정이 추가된다.
ItemSaveForm - Item 저장용 폼
package hello.itemservice.web.validation.form;
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 ItemSaveForm {
@NotBlank
private String itemName;
@NotNull
@Range(min = 1000, max = 1000000)
private Integer price;
@NotNull
@Max(value = 9999)
private Integer quantity;
}
ItemUpdateForm - Item 수정용 폼
package hello.itemservice.web.validation.form;
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;
}
'Spring Study > MVC 패턴' 카테고리의 다른 글
[MVC 패턴] 로그인 처리2 - 필터, 인터셉트 (0) | 2023.08.31 |
---|---|
[MVC 패턴] 로그인 처리1 - 쿠키, 세션 (0) | 2023.08.29 |
[MVC 패턴] 검증1 - Validation (0) | 2023.08.24 |
[MVC 패턴] 메시지, 국제화 (0) | 2023.08.22 |
[MVC 패턴] 타임리프 (Thymeleaf) - 스프링 통합과 폼 (0) | 2023.08.18 |
댓글