관리 메뉴

샐님은 개발중

[Spring boot] Bean Validation - Form 전송 객체 분리 본문

스프링 MVC 2편 - 인프런 김영한/섹션 4 ,5- 검증1,2 - Validation

[Spring boot] Bean Validation - Form 전송 객체 분리

샐님 2023. 7. 13. 20:13
728x90
반응형

기존 

HTML Form -> Item -> Controller ->Item -> Repository

폼 데이터 전달을 위한 별도 객체 사용

HTML Form ->ItemSaveForm ->Controller ->Item ->Respository

장점 : 등록과 수정용으로 별도의 폼 객체를 만들기 때문에 검증이 중복되지 않음.

 

별도 객체 이름을 일관성 있게 짓기.

1. 기존객체 원복

Item.java 

package hello.itemservice.domain.item;

import lombok.Data;
import org.hibernate.validator.constraints.Range;
import org.hibernate.validator.constraints.ScriptAssert;

import javax.validation.constraints.Max;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

@Data
//@ScriptAssert(lang ="javascript",script="_this.price * _this.quantity>= 10000", message="총합이 10000원 넘게 입력해주세요.")
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;
    }
}

 2. 저장 객체 생성

ItemSaveForm.java 

package hello.itemservice.web.validation;

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;
}

3. 수정 객체 생성

ItemUpdateForm.java

package hello.itemservice.web.validation;

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 {
    @NotBlank
    private String itemName;
     @NotNull
     @Range(min = 1000, max = 1000000)
    private Integer price;
    // 수정 폼에서는 무한대 가능
    private Integer quantity;
}

 

4. Controller.java 에서 저장 /수정 로직 메소드 수정

 @PostMapping("/add")
    public String addItem(@Validated @ModelAttribute("item") ItemSaveForm form , BindingResult bindingResult, RedirectAttributes redirectAttributes) {

        /**
         * 복습 : @ModelAttribute() 명은 지정하지않으면 ItemSaveForm 에서 맨앞을 소문자로 바꾼 itemSaveForm 이 들어간다.
         * -> odel.addAtt...("itemSaveForm",form);
         */
        //특정 필드 예외가 아닌 전체 예외
        if (form.getPrice() != null && form.getQuantity() != null) {
            int resultPrice = form.getPrice() * form.getQuantity();
            if (resultPrice < 10000) {
                bindingResult.reject("totalPriceMin", new Object[]{10000,
                        resultPrice}, null);
            }
        }

        //검증에 실패하면 다시 입력 폼으로
        if (bindingResult.hasErrors()) {
            log.info("errors={}",bindingResult);
            return "validation/v4/addForm";
        }
        // 성공 로직
        // Item 객체에 담아서 저장
        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}";
    }


    @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.reject("totalPriceMin", new Object[]{10000,
                        resultPrice}, null);
            }
        }
        //검증에 실패하면 다시 입력 폼으로
        if (bindingResult.hasErrors()) {
            log.info("errors={}",bindingResult);
            return "validation/v4/addForm";
        }

        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}";
    }

 

 

 

728x90
반응형