ThymeLeaf Validation


BindingResult

BindingResult 파라미터의 위치는 반드시 @ModelAttribute 뒤에 와야한다.

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

파라미터넣어야할 값
#fields#fields 로 BindingResult 가 제공하는 검증 오류에 접근할 수 있다.
th:errors해당 필드에 오류가 있는 경우에 태그를 출력한다. th:if의 편의 버전이다.
th:errorclassth:field에서 지정한 필드에 오류가 있으면 class정볼를 추가한다.

BindingResult는 스프링이 제공하는 검증 오류를 보관하는 객체이다. 검증 오류가 발생하면

여기에 보관하면 된다. BindingResult가 있으면 @ModelAttribute에 데이터 바인딩 시

오류가 발생해도 컨트롤러가 호출된다.


BindingResult에 검증 오류를 적용하는 3가지 방밥

@ModelAttribute의 객체 타입 오류 등으로 바인딩이 실패하는 경우 스프링이 FieldError

생성해서 BindingResult에 넣어준다.

⒉ 개발자가 직접 넣어준다.

⒊ Validator 사용


BindingResult와 Errors

BindingResult는 인터페이스이고, Errors 인터페이스를 상속받고 있다.

실제 넘어오는 구현체는 BeanPropertyBindingResult라는 것인데, 둘다 구현하고 있으므로

Errors를 사용해도 된다. 하지만 BindingResult는 addError() 메소드도 제공해준다.


FieldError

첫 번째 생성자

bindingResult.addError(new FieldError("object", "fieldName", "기본 메세지")); 


파라미터넣어야할 값
objectName@ModelAttribute 이름
field오류가 발생한 필드 이름
defaultMessage오류 기본 메세지


<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>
    <input type="text" id="itemName" class="form-control field-error" 
    placeholder="이름을 입력하세요" name="itemName" value="">
    <div class="field-error">
        상품 이름은 필수입니다.
    </div>
</div>


<!-- 정상일 때 -->
<div>
    <input type="text" id="itemName" class="form-control" 
    placeholder="이름을 입력하세요" name="itemName" value="qwer">
</div>


두 번째 생성자

파라미터설명
objectName오류가 발생한 객체 이름
field오류 필드
rejectedValue사용자가 입력한 값(거절된 값)
bindingFailure타입 오류 같은 바인딩 실패인지, 검증 실패인지 구분 값
codes메시지 코드
arguments메시지에서 사용하는 인자
defaultMessage기본 오류 메시지


FieldError는 오류 발생시 사용자 입력 값을 저장하는 기능을 제공한다.

물론 타입 오류로 바인딩에 실해하면 스프링은 FieldError를 생성하면서 사용자가 입력한

값을 넣어둔다. 그리고 해당 오류를 BindingResult에 담아서 컨트롤러를 호출한다.

따라서 타입 오류 같은 바인딩 실패시에도 사용자의 오류 메시지를 정상 출력할 수 있다.


타임리프의 th:field="*{price}"는 매우 똑똑하게 동작한다. 정상 상황에는 모델 객체의

값을 사용하지만, 오류가 발생하면 FieldError에서 보관한 값을 사용해서 값을 출력한다.



글로벌 오류 - ObjectError

bindingResult.addError(new ObjectError("objectName","기본 메세지"))


파라미터넣어야할 값
objectName@ModelAttribute 이름
defaultMessage오류 기본 메세지


<div th:if="${#fields.hasGlobalErrors()}">
    <p class="field-error" th:each="err:${#fields.globalErrors()}" th:text="${err}">
</div>