-
상품 수정 검증, 검증 groups - V3스프링/스프링 MVC 패턴 2023. 2. 25. 16:50
@PostMapping("/{itemId}/edit") public String edit(@PathVariable Long itemId, @Validated @ModelAttribute Item item, BindingResult bindingResult) { if (item.getPrice() != null && item.getQuantity() != null ) { int resultPrice = item.getPrice() * item.getQuantity(); if (resultPrice < 10000) { bindingResult.addError(new ObjectError("item", "가격 * 수량의 합은 10,000원 이상이어야 합니다. 현재 값 = " + resultPrice)); } } if(bindingResult.hasErrors()) { log.info("errors={}", bindingResult); return "validation/v3/editForm"; } itemRepository.update(itemId, item); return "redirect:/validation/v3/items/{itemId}"; } }
컨트롤러에 있는 상품 수정 메서드에 추가 코드를 넣어두었다. 수정한 부분은 @Validated와 bindingResult의 추가와 가격 * 수량 오류, 에러코드 출력 코드이다.
editForm.html
글로벌 오류
<div th:if="${#fields.hasGlobalErrors()}"> <p class="field-error" th:each="err : ${#fields.globalErrors()}" th:text="${err}">글로벌 오류 메시지</p> </div>
상품명 오류
<label for="price" th:text="#{label.item.price}">가격</label> <input type="text" id="price" th:field="*{price}" th:errorclass="field-error" class="form-control"> <div class="field-error" th:errors="*{price}"> 가격 오류 </div>
editForm에 글로벌 오류와 상품명 오류, 가격 오류, 수량 오류가 발생했을 시의 추가 코드를 넣어주었다.
앞 게시글에서 addForm에 있던 코드와 동일하니 설명은 생략하겠다.
Bean Validation의 한계
Bean Validation은 동시성의 한계가 있다. 만약에 등록할 때와 수정할 때의 기준이 다르다고 한다면 Bean Validation으로 효율적인 개발을 할 수가 없다. 등록할 때에는 수량 제한이 있지만 수정할 때에는 수량 제한을 없앤다고 했을 때 등록할 때와 수정할 때의 각각 다른 검증을 해야할 때 추가 기능을 사용해야한다.
groups
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;
SaveCheck와 UpdateCheck 인터페이스는 아래와 같은 아무것도 없는 빈 인터페이스이다.
package hello.itemservice.domain.item; public interface SaveCheck { }
public String addItem(@Validated(SaveCheck.class) @ModelAttribute Item item, BindingResult bindingResult, RedirectAttributes redirectAttributes) {
public String edit(@PathVariable Long itemId, @Validated(UpdateCheck.class) @ModelAttribute Item item, BindingResult bindingResult) {
컨트롤러의 addItem과 edit 메서드에 @Validated뒤에 class를 넣어주면 group에서 설정한 에러만 처리된다.
등록과 수정의 에러 기준을 따로 설정할 수 있게 된다는 것이다.
하지만 실무에서는 부가 정보가 많이 넘어오기 때문에 등록과 수정은 분리해야해서 groups는 잘 사용하지 않는다고 한다.
'스프링 > 스프링 MVC 패턴' 카테고리의 다른 글
상품 등록 전 로그인하기 - 회원가입 페이지 만들기 (0) 2023.02.28 등록과 수정의 검증 분리 - V4 (0) 2023.02.25 스프링 자동 검증기(Bean Validation) (0) 2023.02.25 Validation 분리 (0) 2023.02.23 오류 코드와 메시지 처리 (0) 2023.02.23