Bean Validation
검증 로직을 모든 프로젝트에 적용할 수 있게 공통화하고, 표준화 한 것.
애노테이션 하나로 로직을 편리하게 적용 가능.
build.gradle 의존성 추가
implementation 'org.springframework.boot:spring-boot-starter-validation’
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; //...
}
타입 변환에 성공해서 바인딩에 성공한 필드에만 BeanValidation이 적용된다.
실패시 typeMismatch FieldError 추가, BeanValidation 적용 X
groups
등록과 수정을 다르게 검증할 수 있다.
Form 전송 객체 분리
실무에서는 Item 과 관계없는 수 많은 부가 데이터가 넘어온다.
그래서 보통 Item 을 직접 전달받는 것이 아니라, 복잡한 폼의 데이터를 컨트롤러까지 전달할 별도의 객체를 만들어서 전달한다.
폼을 전달받는 전용 객체를 만들어서 @ModelAttribute 로 사용한다.
이것을 통해 컨트롤러에서 폼 데이터를 전달 받고, 이후 컨트롤러에서 필요한 데이터를 사용해서 Item 을 생성한다.
@Data
public class ItemSaveForm {
@NotBlank
private String itemName;
@NotNull
@Range(min = 1000, max = 1000000)
private Integer price;
@NotNull
@Max(value = 9999)
private Integer quantity;
}
@Data
public class ItemUpdateForm {
@NotNull
private Long id;
@NotBlank
private String itemName;
@NotNull
@Range(min = 1000, max = 1000000)
private Integer price;
//수정에서는 수량은 자유롭게 변경할 수 있다.
private Integer quantity;
}
@PostMapping("/add")
public String addItem(@Validated @ModelAttribute("item") ItemSaveForm form, BindingResult
bindingResult, RedirectAttributes redirectAttributes) {
}
@PostMapping("/{itemId}/edit")
public String edit(@PathVariable Long itemId, @Validated @ModelAttribute("item") ItemUpdateForm form, BindingResult bindingResult) {
}
등록에서는 ItemSaveForm 호출, 수정에는 ItemUpdateForm 호출.
HTTP 메시지 컨버터
3가지 경우
@ModelAttribute vs @RequestBody
HttpMessageConverter 는 @ModelAttribute 와 다르게 각각의 필드 단위로 적용되는 것이 아니라, 전체 객체 단위로 적용된다.
따라서 메시지 컨버터의 작동이 성공해서 ItemSaveForm 객체를 만들어야 @Valid , @Validated 가 적용된다.