
스프링 검증 방식 - BindingResult 사용
BindingResult



#글로벌 오류 처리
<div th:if="${#fields.hasGlobalErrors()}">
<p class="field-error" th:each="err : ${#fields.globalErrors()}" th:text="${err}">
전체 오류 메시지
</p>
</div>
#필드 오류 처리
```html
<input type="text" id="itemName" th:field="*{itemName}" th:errorclass="field-error" class="form-control" placeholder="이름을 입력하세요" />
<div class="field-error" th:errors="*{itemName}">
상품명 오류
</div>

BindingResult의 FieldError 활용

BindingResult의 rejectValue(), reject() 활용
bindingResult.addError(new FieldError("item", "price", item.getPrice(), false, new String[]{"range.item.price"}, new Object[]{1000, 1000000}, null));
#resultValue 를 이용한 변환 처리 위의 코드를 아래의 코드로 변환
bindingResult.rejectValue("price", "range", new Object[]{1000, 1000000}, null);
중요 Message Properties 설계 팁

Level1 이 먼저 적용되기 때문에 Level2 의 "필수 값 입니다." 를 글로벌로 등록해 놓고
디테일하게 메세지가 필요할 경우 Level1 과 같이 "상품 이름은 필수 입니다." 라는
require.item.itemName 값을 추가 해주면 상품이름은 Level1 이 적용되지만 나머지는
모두 Level2 메세지로 처리 된다.
MessageCodesResolver
public class MessageCodesResolverTest {
MessageCodesResolver codesResolver = new DefaultMessageCodesResolver();
@Test
void messageCodesResolverObject() {
String[] messageCodes = codesResolver.resolveMessageCodes("required", "item");
assertThat(messageCodes).containsExactly("required.item", "required");
}
@Test
void messageCodesResolverField() {
String[] messageCodes = codesResolver.resolveMessageCodes("required", "item", "itemName", String.class);
assertThat(messageCodes).containsExactly(
"required.item.itemName",
"required.itemName",
"required.java.lang.String",
"required"
);
}
}
Message Properties 판단하는 우선 순위
1순위 : required.item.itemName,
2순위 : required.itemName,
3순위 : required.java.lang.String,
4순위 : required



ValidationUtil 필요하면 사용
WebDataBinder 활용한 Validator

@InitBinder
public void init(WebDataBinder dataBinder) {
log.info("init binder {}", dataBinder);
dataBinder.addValidators(itemValidator);
}
하단에 추가 된 ItemValidator 참고
@Component
public class ItemValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
return Item.class.isAssignableFrom(clazz);
}
@Override
public void validate(Object target, Errors errors) {
Item item = (Item) target;
}
}



출처 김영한의 스프링 로드맵 - 스프링 MVC 2편 - 백엔드 웹 개발 핵심 기술