Bean Validation (2)

JIWOO YUN·2024년 2월 15일
0

SpringMVC2

목록 보기
15/26
post-custom-banner

오브젝트 오류(글로벌 오류)

  • BealValidation에서 해당 오브젝트 오류 관련 오류를 처리하는 방법
  • @ScriptAssert()를 사용해서 진행
    • 하지만 제약이 많고 복잡해서 굳이 사용하지 않고 직접 자바코드로 작성하는 것이 좋다고 한다.

@ScriptAssert()를 사용하지 않고 직접 자바코드로 글로벌 오류를 처리

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

        //직접 자바코드로 작성해서 글로벌 오류를 잡아준다.
        if(item.getPrice() != null && item.getQuantity() != null){
            int resultPrice = item.getPrice() * item.getQuantity();
            if(resultPrice < 10000){
                bindingResult.reject("totalPriceMin",new Object[]{10000,resultPrice},null);
            }
        }


        if(bindingResult.hasErrors()){
            log.info("target = {}",bindingResult.getTarget());
            return "validation/v3/addForm";
        }


        //성공 로직
        Item savedItem = itemRepository.save(item);
        redirectAttributes.addAttribute("itemId", savedItem.getId());
        redirectAttributes.addAttribute("status", true);
        return "redirect:/validation/v3/items/{itemId}";
    }

수정시 검증 요구사항을 체크 필수

  • 데이터를 등록할 때와 수정할 때는 요구사항이 다를수 있다.
  • 수정시에는 수량을 무제한으로 변경 할 수있음.
  • 수정시에는 id 값이 필수.

수정시에도 현재 요구사항 문제를 해결하기 위해서 items를 수정해준다.

@Data
public class Item {



    @NotNull
    private Long id;

    @NotBlank(message = "공백은 입력할 수 없습니다.")
    private String itemName;

    @NotNull
    @Range(min=1000,max = 1000000)
    private Integer price;

    @NotNull
//    @Max(9999)
    private Integer quantity;


    public Item() {

    }

    public Item(String itemName, Integer price, Integer quantity) {
        this.itemName = itemName;
        this.price = price;
        this.quantity = quantity;
    }
}
  • 근데 이렇게 할 경우 수정에는 문제가 없어지지만 등록때에 문제가 발생한다.
    • 등록시에는 id 값이 없기 때문에 null로 에러가 발생
    • 등록시 quantity의 최대값인 9999도 적용되지 않음.

이문제를 해결하기 위해서는 2가지 방법이 존재한다.

  1. BeanValidation의 groups 기능을 사용한다.
  2. Item 을 직접 사용하지 않고, ItemSaveForm, ItemUpdateForm 같은 폼 전송을 위한 별도의 모델 객체를 만들어서 사용.

여기서 진행할것은 groups기능을 사용할 것이다.

  • 등록시에 검증할 기능과 수정시에 검증할 기능을 각각 그룹으로 나누어 적용하는게 가능해진다.

저장용 SaveCheck 인터페이스와 UpdateCheck 인터페이스를 생성

저장로직에 SaveCheck Groups 를 적용시켜준다.

@PostMapping("/add")
public String addItem(@Validated(SaveCheck.class) @ModelAttribute("item") Item item, BindingResult bindingResult,
                      RedirectAttributes redirectAttributes) {

수정로직에는 UpdateCheck Groups를 적용

@PostMapping("/{itemId}/edit")
public String edit(@PathVariable("itemId")Long itemId, @Validated(UpdateCheck.class) @ModelAttribute Item item, BindingResult bindingResult){

주의점 : @Valid는 Groups를 적용하는 기능이 없기 때문에 @Validated를 사용해야함.

전반적으로 복잡도가 증가하기 때문에 그렇게 권장하는 방법이 아니다.

  • 실무에서는 2번째 방법인 각 폼을 따로 분리해서 사용한다고 한다.
  • 거기에 바로 등록시 폼에서 전달하는 데이터가 Item 도메인 객체와 딱 맞지 않기 때문에 사용되지않는다.
    • 실무에서는 회원 과 관련된 데이터만 전달 받는게 아닌 약관 정보 등의 Item과 관계없는 수많은 부가 데이터가 넘어오기 때문에

profile
열심히하자
post-custom-banner

0개의 댓글