ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 상품 수정 검증, 검증 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는 잘 사용하지 않는다고 한다.

Designed by Tistory.