검증 (validation) - BindingResult

junheelee·2022년 11월 2일
0

SpringMVC

목록 보기
19/19

BindingResult ?

검증 오류 (HTTP 파라미터 또는 Controller 로직)가 발생할 경우에 해당 오류의 내용을 보관하는 스프링 프레임워크 객체

BindingResult 주의

  • BindingResult는 검증할 대상 바로 다음에 와야함.
    ex) @ModelAttribute Test test, BindingResult bindingResult
  • Model에 직접 넣어주는 작업을 하지 않아도 된다.

참고

BindingResult : interface

Errors : interface

Error -> BindingResult 상속

BindingResult - controller

@PostMapping("/add")
public String addItemV1(@ModelAttribute Item item,
                          BindingResult bindingResult,
                          RedirectAttributes redirectAttributes,
                          Model model) {
        /**
         * BindingResult ?
         * @ModelAttribute 다음에 와야한다.
         * modelAttribute에 담는 과정은 필요 없음.
         */
        //검증 오류 결과 보관 과정 생략 
        //Map<String, String> errors = new HashMap<>();
        //특정 필드 검증 로직
        if(!StringUtils.hasText(item.getItemName())) {
            bindingResult.addError(new FieldError("item", "itemName", "상품 이름은 필수 입니다."));
        }
        if(item.getPrice() == null || item.getPrice() < 1000 || item.getPrice() > 1000000) {
            bindingResult.addError(new FieldError("item", "price", "상품 금액은 1,000원 ~ 1,000,000원 사이 가격을 입력해주세요."));
        }
        if(item.getQuantity() == null || item.getQuantity() >=9999) {
            bindingResult.addError(new FieldError("item", "quantity", "수량은 9,999개 이하로 입력해주세요."));
        }
        //특정 필드가 아닌 복합 룰 검증
        if(item.getPrice() != null && item.getQuantity() != null) {
            int resultPrice = item.getPrice() * item.getQuantity();
            if (resultPrice < 10000) {
                bindingResult.addError(new ObjectError("item", "가격 X 수량은 10,000원 이상이여야 합니다. (현재입력=" + resultPrice + ")"));
            }
        }
        //검증 조건 미충족시 다시 입력 폼으로
        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 - html

global error

<div th:if="${#fields.hasGlobalErrors()}">
 <p class="field-error" th:each="err : ${#fields.globalErrors()}"
th:text="${err}">글로벌 오류 메시지
  </p>
 </div>

global error는 방대한 분량을 가지고 있어서 반복해서 출력

field error

<div>
 	<label for="itemName" th:text="#{label.item.itemName}">
   		상품명
  	</label>
 <input type="text" id="itemName" th:field="*{itemName}"
 		th:errorclass="field-error" class="form-control" placeholder="이름을 입력하세요">

  	<div class="field-error" th:errors="*{itemName}">
 		상품명 오류
 	</div>
 </div>

🪴 원리

타임리프는 스프링의 BindingResult를 활용 할 수 있다.

  • #fields: #fields로 BindingResult 접근
  • th:errors : 해당 필드의 오류가 있는 경우 태그 출력
  • th:errorclass: th:field에 지정한 필드에 오류가 있으면 class 출력
profile
Study of beginner dev

0개의 댓글