Bean Validation - 3

    Bean Validation - 오브젝트 오류

    Bean Validation에서 특정필드(FieldError)가 아닌 해당 오브젝트 관련 오류(ObjectError)는 어떻게 처리할 수 있는가?

    @ScriptAssert() 사용하면 된다.

    @Data
    @ScriptAssert(lang = "javascript", script = "_this.price * _this.quantity >= 10000")
    public class Item {
     //...
    }

     

    메시지 코드

    • ScriptAssert.item
    • ScriptAssert

    그러나 사용해 보면 제약이 많고 복잡하다. 검증 기능이 해당 객체의 범위를 넘는 경우가 있는데 그럴 경우 대응이 어렵다.

    따라서 오브젝트 오류(글로벌 오류)의 경우 @ScriptAssert를 억지로 사용하는 것보다는 오브젝트 오류 관련 부분만 자바 코드로 작성하는 것을 권장한다고 한다.

     

    @ScriptAssert 제거 후 검증 로직 자바코드로 직접 추가

    		// 특정 필드가 아닌 복합 룰 검증
            if (item.getPrice() != null && item.getQuantity() != null){
                int resultPrice = item.getPrice() * item.getQuantity();
                if (resultPrice < 10000){
                    bindingResult.reject("totalPriceMin", new Object[]{10000, resultPrice}, null);
                }
            }

     

    수정 에 추가

    • .field-error css 추가
    • 글로벌 오류 메시지
    • 상품명, 가격, 수량 필드에 검증 기능 추가
    <!DOCTYPE HTML>
    <html xmlns:th="http://www.thymeleaf.org">
    <head>
     	<meta charset="utf-8">
     	<link th:href="@{/css/bootstrap.min.css}"
     			 href="../css/bootstrap.min.css" rel="stylesheet">
     	<style>
     		.container {
     			max-width: 560px;
     		}
     		.field-error {
     			border-color: #dc3545;
     			color: #dc3545;
     		}
     	</style>
    </head>
    <body>
    	<div class="container">
     	<div class="py-5 text-center">
     		<h2 th:text="#{page.updateItem}">상품 수정</h2>
     	</div>
     		<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="id" th:text="#{label.item.id}">상품 ID</label>
     			<input type="text" id="id" th:field="*{id}" class="form-control" readonly>
     		</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>
    		<hr class="my-4">
     		<div class="row">
     		<div class="col">
     			<button class="w-100 btn btn-primary btn-lg" type="submit" th:text="#{button.save}">저장</button>
     		</div>
     		<div class="col">
     			<button class="w-100 btn btn-secondary btn-lg" onclick="location.href='item.html'"
     					th:onclick="|location.href='@{/validation/v3/items/{itemId}(itemId=${item.id})}'|" type="button" th:text="#{button.cancel}">취소</button>
     		</div>
     	</div>
     </form>
    </div> <!-- /container -->
    </body>
    </html>

     

    'SPRING' 카테고리의 다른 글

    Bean Validation - 5  (1) 2023.12.20
    Bean Validation - 4(groups)  (0) 2023.12.20
    Bean Validation - 2(스프링 적용)  (1) 2023.12.20
    Bean Validation - 1  (0) 2023.12.19
    @Target, @Retention  (0) 2023.10.18

    댓글