Validation2

shinyeongwoon·2023년 1월 20일
0

Message

목록 보기
4/11

BindingResult1

핵심은 BindingResult이다.

ValidationItemControllerV2 - addItemV1

@PostMapping("/add")
public String addItemV1(@ModelAttribute Item item, BindingResult bindingResult,RedirectAttributes redirectAttributes) {
	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() > 10000) {
    	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", "가격 * 수량의 합은 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 bindingResult 파라미터의 위치는 @ModelAttribute Item item 다음에 와야 한다.

필드 오류 - FieldError

if (!StringUtils.hasText(item.getItemName())) { 
	bindingResult.addError(new FieldError("item", "itemName", "상품 이름은필수입니다.")); 
}

FieldError 생성자 요약

public FieldError(String objectName, String field, String defaultMessage) {}

필드에 오류가 있으면 FieldError 객체를 생성해서 bindingResult 에 담아두면 된다. - objectName : @ModelAttribute 이름

  • field : 오류가 발생한 필드 이름
  • defaultMessage : 오류 기본 메시지

글로벌 오류 - ObjectError

bindingResult.addError(new ObjectError("item", "가격 * 수량의 합은 10,000원 이상이어야 합니다. 현재 값 = " + resultPrice));

ObjectError 생성자 요약

public ObjectError(String objectName, String defaultMessage) {}

특정 필드를 넘어서는 오류가 있으면 ObjectError 객체를 생성해서 bindingResult 에 담아두면 된다.

  • objectName : @ModelAttribute 의 이름
  • defaultMessage : 오류 기본 메시지

validation/v2/addForm.html 수정

<form action="item.html" th:action th:object="${item}" method="post">
  <div th:if="${#fields.hasGlobalErrors()}">
    <p class="field-error" th:each="err : ${#fields.globalErrors()}" th:text="${err}">글로벌 오류 메시지
    </p> 
  </div>
  <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>
  <div>
    <label for="price" th:text="#{label.item.price}">가격</label>
    <input type="text" id="price" th:field="*{price}" th:errorclass="field-error" class="form-control" placeholder="가격을 입력하세요">
    <div class="field-error" th:errors="*{price}">
      가격 오류
    </div>
  </div>
  <div>
    <label for="quantity" th:text="#{label.item.quantity}">
      수량
    </label>
    <input type="text" id="quantity" th:field="*{quantity}" th:errorclass="field-error" class="form-control" placeholder="수량을 입력하세요">
    <div class="field-error" th:errors="*{quantity}">
      수량 오류
    </div>
</div>

타임리프 스프링 검증 오류 통합 기능

타임리프는 스프링의 BindingResult 를 활용해서 편리하게 검증 오류를 표현하는 기능을 제공한다.

  • #fields : #fieldsBindingResult 가 제공하는 검증 오류에 접근할 수 있다.
  • th:errors : 해당 필드에 오류가 있는 경우에 태그를 출력한다. th:if 의 편의 버전이다.
  • th:errorclass : th:field 에서 지정한 필드에 오류가 있으면 class 정보를 추가한다.

검증과 오류 메시지 공식 메뉴얼
https://www.thymeleaf.org/doc/tutorials/3.0/thymeleafspring.html#validation-and-error-messages

글로벌 오류 처리

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

필드 오류 처리

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

0개의 댓글