
본 게시물은 스스로의 공부를 위한 글입니다.
틀린 내용이 있을 수 있습니다.
public String addItem(@ModelAttribute Item item, BindingResult bindingResult) {
if (!StringUtils.hasText(item.getItemName())) {
bindingResult.addError(new FieldError("item", "itemName", "상품 이름은 필수입니다."));
}
BindingResult bindingResult 파라미터의 위치는 반드시 @ModelAttribute Item item 다음에 바로 와야 한다.FieldError(String objectName, String field, String defaultMessage)FieldError(검증 객체 이름, 오류가 발생한 필드 이름, 오류 기본 메시지)bindingResult.addError(new ObjectError("item", "가격 * 수량의 합은 10,000원 이상이어야 합니다. 현재 값 = " + resultPrice));
ObjectError(String objectName, String defaultMessage)ObjectError(@ModelAttribute 이름, 오류 기본 메시지)<input type="text" th:field="${price}" th:errorclass="field-error" class="form-control" placeholder="가격을 입력하세요">
<div class="field-error" th:errors="*{price}"> 가격 오류 </div>
th:errorclassth:field에서 지정한 필드에 오류가 있으면 class정보 추가th:errorsth:if의 편의버전이다.<div th:if="${#fields.hasGlobalErrors()}">
<p class="field-error" th:each="err : ${#fields.globalErrors()}" th:text="${err}">글로벌 오류 메시지</p>
</div>
#fields로 BindingResult가 제공하는 검증 오류에 접근할 수 있다.BindingResult가 인자로 없으면BindingResult가 인자로 있으면fieldError를 만들고 BindingResult에 담아서 컨트롤러를 정상 호출한다.BindingResult에 검증 오류를 적용하는 3가지 방법
@ModelAttribute 의 객체에 타입 오류 등으로 바인딩이 실패하는 경우 스프링이 FieldError 생성해서 BindingResult 에 넣어준다.
개발자가 직접 넣어준다.
Validator 사용
BindingResult에 들어간다. FieldError의 또다른 생성자.
FieldError(String objectName, String field, @Nullable Object rejectedValue, boolean bindingFailure, @Nullable String[] codes, @Nullable Object[] arguments, @Nullable String defaultMessage)FieldError(오류 발생 객체 이름, 오류 필드, 사용자가 입력한 값(거절된 값), 바인딩실패?, 메시지 코드, 메시지에 이용하는 인자, 기본 메시지)ObjectError도 field부분만 빼고 동일하다.
이를 통해 사용자가 입력한 오류값이 그대로 남아있게 할 수 있다.(rejectedValue를 통해서 가능.)
바인딩 오류시에는 스프링이 알아서 사용자 입력 값을 담은 FieldError을 생성해 BindingResult에 넣어주니, 크게 신경쓰지 않아도 알아서 해준다.
th:field는 정상 상황에서는 모델 객체 값을 사용하지만, 해당 필드의 오류 발생시 FieldError에 담긴 필드값을 사용한다. 즉, 사용자가 입력한 오류 값을 사용하므로 사용자에게 그대로 보여줄 수 있다.FieldError, ObjectError의 생성자는 errorCode,arguments를 제공한다. 이것은 오류 발생시 오류 코드로 메시지를 찾기 위해 사용된다.
스프링 부트는 기본 설정으로 src/main/resources/messages.properties에서 메시지를, src/main/resources/ValidationMessages.properties에서 유효성 검사에 대응하는 (에러)메시지를 가져온다.
application.properties에 spring.messages.basename=messages,errors추가
## `src/main/resources/errors.properties`에
required.item.itemName=상품 이름은 필수입니다.
range.item.price=가격은 {0} ~ {1} 까지 허용합니다.
max.item.quantity=수량은 최대 {0} 까지 허용합니다.
totalPriceMin=가격 * 수량의 합은 {0}원 이상이어야 합니다. 현재 값 = {1}
bindingResult.addError(new FieldError("item", "price", item.getPrice(), false, new String[]{"range.item.price"}, new Object[]{1000, 1000000}, null))
bindingResult.addError(new ObjectError("item", new String[] {"totalPriceMin"}, new Object[]{10000, resultPrice}, null))
errorCode와 errorArgs가 있다.errors.properties에 오류 메시지를 만들어두면, 스프링에 이에 맞는 오류 메시지를 찾는다.오류 메시지는 MessageCodesResolver이 맡는데, 오류 메시지를 찾는 메커니즘을 알아보자
객체 오류
필드 오류
cf 바인딩에 실패하면 BindingReuslt는 typeMismatch라는 errorCode를 자동으로 넣는다.
BindingResult는 Object가 뭔지 알고있기 때문에(인자에서 오브젝트 바로 뒤에 쓰기 때문이다) 생략 가능하다.Object를 생략한 rejectValue, rejcet를 사용해보자.rejectValue(@Nullable String field, String errorCode, @Nullable Object[] errorArgs, @Nullable String defaultMessage);bindingResult.rejectValue("price", "range", new Object[]{1000, 1000000}, null)reject(String errorCode, @Nullable Object[] errorArgs, @Nullable String defaultMessage);사실 스프링에서 검증할땐 거의 대부분
Bean Validation을 사용한다. 다음 게시물에서 자세히 알아보자.
인프런의 '스프링 MVC 2편(김영한)'을 스스로 정리한 글입니다.
자세한 내용은 해당 강의를 참고해주세요