스프링/4. 스프링 MVC-2

30. FieldError, ObjectError

sdafdq 2023. 8. 29. 23:35
@PostMapping("/add")
public String addItemV2(@ModelAttribute Item item, BindingResult bindingResult, RedirectAttributes redirectAttributes, Model model) {
    //검증 오류 보관


    //검증 로직
    if(!StringUtils.hasText(item.getItemName())){
        bindingResult.addError(new FieldError("item", "itemName", item.getItemName(), false, null, null, "상품 이름은 필수입니다."));
    }
    if(item.getPrice() == null || item.getPrice() < 1000 || item.getPrice() > 1000000){
        bindingResult.addError(new FieldError("item", "price", item.getPrice(), false, null, null, "가격은 1,000 ~ 1,000,000 까지 허용합니다."));
    }
    if(item.getQuantity() == null || item.getQuantity() > 9999){
        bindingResult.addError(new FieldError("item", "quantity", item.getQuantity(), false, null, null, "수량은 최대 9,999개 까지 허용합니다."));
    }


//        복합에러
    if(item.getPrice() != null && item.getQuantity() != null){
        int result = item.getQuantity() * item.getPrice();
        if(result < 10000){
            bindingResult.addError(new ObjectError("item", "가격 * 수량의 합은 10,000원 이상이어야 합니다. 현재값 = \" + result"));
            bindingResult.addError(new ObjectError("item", null, null, "가격 * 수량의 합은 10,000원 이상이어야 합니다. 현재값 = \" + result"));
        }
    }

    if(bindingResult.hasErrors()){
        log.info("errors = {}", bindingResult);
        return "/validation/v2/addForm";
    }


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

원래 기존은 에러 나고나면 내가 입력한 값이 지워졌다.

이번에 바뀐 점은, 

bindingResult.addError(new FieldError("item", "itemName", item.getItemName(), false, null, null, "상품 이름은 필수입니다."));

인자가 많아졌다.

순서대로

오브젝트 이름

필드이름

오류날 시 대신 넣을 값

타입오류인지?

코드

메시지에서 사용하는 인자라는데 아직 모르겠다.

메시지

 

이렇게 해서 저 오류날 시 대신 넣을 값에 저렇게 post니 item으로 값이 넘어왔을 테고 그 값을 저렇게 넣으면 사용자가 입력한 값을 그대로 넣어준다.

 

 

그리고, 보면 알지만 먼저 인자로 값을 바인딩하는게 먼저기 때문에, 타입오류를 먼저 잡고, 그 다음 내 로직따라 검증에러를 잡는거다.

 

만약 타입에러가 날 시,

bindingResult.addError(new FieldError("item", "price", 입력받은값, true, null, null, "상품 이름은 필수입니다."));

 

이렇게 reject 부분에 담기 때문에 숫자가 아니더라도 사용자의 입력값을 그대로 넣어놓을 수 있다.

 

 

그리고 이게 템플릿에서 사용자의 값을 똑같이 넣어서 보여줄 수 있는 이유는,

th:field 덕분인데,

얘가 정상 상황에서는 모델객체의 값을 사용하지만,

에러 발생 시엔 FieldError에 보관한 값을 넣어주는거임.

 

쟤가 많은 일을 함. 

'스프링 > 4. 스프링 MVC-2' 카테고리의 다른 글

32. 오류 메시지 2  (0) 2023.09.02
31. 오류 메시지 처리  (0) 2023.09.02
29. BindingResult2  (0) 2023.08.29
28. BindingResult  (0) 2023.08.29
27. 검증 직접 구현  (0) 2023.08.28