ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 등록과 수정의 검증 분리 - V4
    스프링/스프링 MVC 패턴 2023. 2. 25. 17:37

    등록과 수정은 항상 같은 값들이 넘어오는 것이 아니라 부가적인 데이터가 많기 때문에 등록과 수정을 분리해주는 것이 좋다.

     

     

    등록을 위한 ItemSaveForm

    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

    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 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) {
        // @Validated가 검증을 알아서 해주고 bindingResult에 결과를 담아준다.
        // @ModelAttribute에 ("item")필수!! 안하면 itemSaveForm이 넘어감
    
        if (form.getPrice() != null && form.getQuantity() != null ) {
            int resultPrice = form.getPrice() * form.getQuantity();
            if (resultPrice < 10000) {
                bindingResult.addError(new ObjectError("item", "가격 * 수량의 합은 10,000원 이상이어야 합니다. 현재 값 = " + resultPrice));
            }
        }
    
        // 검증에 실패하면 다시 입력 폼으로 이동하는 로직
        if (bindingResult.hasErrors()) {
            log.info("errors = {}", bindingResult);
            // model.addAttribute("errors", errors); // bindingResult가 자동으로 모델에 넘어가서 생략해도 됨
            return "validation/v4/addForm";
        }
    
    
        // 아래는 에러가 없을 때의 성공 로직
        Item item = new Item();
        item.setItemName(form.getItemName());
        item.setPrice(form.getPrice());
        item.setQuantity(form.getQuantity());
        // 객체를 따로 생성해서 넣어줘야함
    
        Item savedItem = itemRepository.save(item);
        redirectAttributes.addAttribute("itemId", savedItem.getId());
        redirectAttributes.addAttribute("status", true);
        return "redirect:/validation/v4/items/{itemId}";
    }

    @ModelAttribute Item item이었는데 Item 객체가 아니라 ItemSaveForm 클래스를 가져와서 form을 만들어 준다.

    이 때 @ModelAttribute("item")을 무조건 해줘야지만 html 파일에 바인딩이 잘 이루어진다. 이 경우에는 등록을 위한 ItemSaveForm 객체를 파라미터로 넘긴것이기 때문에 등록에 성공할 경우에는 Item 객체를 따로 생성해서 form의 값들을 Item 객체에 넣어줘야한다.

     

     

     

     

    @PostMapping("/{itemId}/edit")
    public String edit(@PathVariable Long itemId, @Validated @ModelAttribute("item") ItemUpdateForm form, BindingResult bindingResult) {
    
        if (form.getPrice() != null && form.getQuantity() != null ) {
            int resultPrice = form.getPrice() * form.getQuantity();
            if (resultPrice < 10000) {
                bindingResult.addError(new ObjectError("item", "가격 * 수량의 합은 10,000원 이상이어야 합니다. 현재 값 = " + resultPrice));
            }
        }
    
        if(bindingResult.hasErrors()) {
            log.info("errors={}", bindingResult);
            return "validation/v4/editForm";
        }
    
        Item itemParam = new Item();
        itemParam.setItemName(form.getItemName());
        itemParam.setPrice(form.getPrice());
        itemParam.setQuantity(form.getQuantity());
    
        itemRepository.update(itemId, itemParam);
        return "redirect:/validation/v4/items/{itemId}";
    }

    상품 수정도 같은 방식으로 진행 되었으며 ItemUpdateForm 클래스를 사용했다.

Designed by Tistory.