#required.item.itemName=상품 이름은 필수입니다.
#range.item.price=가격은 {0} ~ {1} 까지 허용합니다.
#max.item.quantity=수량은 최대 {0} 까지 허용합니다.
#totalPriceMin=가격 * 수량의 합은 {0}원 이상이어야 합니다. 현재 값 = {1}
#==ObjectError==
#Level1
totalPriceMin.item=상품의 가격 * 수량의 합은 {0}원 이상이어야 합니다. 현재 값 = {1}
#Level2 - 생략
totalPriceMin=전체 가격은 {0}원 이상이어야 합니다. 현재 값 = {1}
#==FieldError==
#Level1
required.item.itemName=상품 이름은 필수입니다.
range.item.price=가격은 {0} ~ {1} 까지 허용합니다.
max.item.quantity=수량은 최대 {0} 까지 허용합니다.
#Level2 - 생략
#Level3
required.java.lang.String = 필수 문자입니다.
required.java.lang.Integer = 필수 숫자입니다.
min.java.lang.String = {0} 이상의 문자를 입력해주세요.
min.java.lang.Integer = {0} 이상의 숫자를 입력해주세요.
range.java.lang.String = {0} ~ {1} 까지의 문자를 입력해주세요.
range.java.lang.Integer = {0} ~ {1} 까지의 숫자를 입력해주세요.
max.java.lang.String = {0} 까지의 문자를 허용합니다.
max.java.lang.Integer = {0} 까지의 숫자를 허용합니다.
#Level4
required = 필수 값 입니다.
min= {0} 이상이어야 합니다.
range= {0} ~ {1} 범위를 허용합니다.
max= {0} 까지 허용합니다.
if (item.getPrice() == null || item.getPrice() < 1000 || item.getPrice() > 1000000) {
bindingResult.addError(new FieldError("item", "price", item.getPrice(), false, new String[]{"range.item.price", "range.default"}, new Object[]{"1000","1000000"}, null));
}
// 특정 필드가 아닌 복합 룰 검증
if (item.getPrice() != null && item.getQuantity() != null) {
int resultPrice = item.getPrice() * item.getQuantity();
if (resultPrice < 10000) {
// 특정 필드 에러가 아닌 글로벌 에러이므로 ObjectError로 담아줌
bindingResult.addError(new ObjectError("item",new String[]{"totalPriceMin"}, new Object[]{10000, resultPrice}, "가격 * 수량의 합은 10,000원 이상이어야 합니다. 현재 값 = " + resultPrice));
}
}
필드와 관련된 에러 메세지를 띄울 때 사용하며
FieldError를 활용한다.
addError(new FieldError(objectName, field, rejectedValue, bindingFailure, codes, arguments, defaultMessage))
이런 순서로 파라미터를 지정해줘야 하는데, 각 파라미터에는 다음과 같은 값이 들어간다
objectName : 오류가 발생한 객체 이름
field : 오류 필드
rejectedValue : 사용자가 입력한 값(거절된 값)
bindingFailure : 타입 오류 같은 바인딩 실패인지, 검증 실패인지 구분 값
codes : 메시지 코드
arguments : 메시지에서 사용하는 인자
defaultMessage : 기본 오류 메시지
codes에는 문자타입의 배열({"range.item.price", "range.default"})이 들어가는 것을 알 수 있는데, 이는 에러 코드의 우선순위로 "range.item.price"라는 키 값이 errors.properties에 존재한다면 그 값을 띄우고 존재하지 않는다면 "range.default"를 띄운다.
arguments에는 Object타입의 배열이 들어간다.
// FieldError(필드에러)
if (item.getPrice() == null || item.getPrice() < 1000 || item.getPrice() > 1000000) {
bindingResult.rejectValue("price", "range", new Object[]{1000, 1000000},null
);
}
// ObjectError(글로벌 에러)
if (item.getPrice() != null && item.getQuantity() != null) {
int resultPrice = item.getPrice() * item.getQuantity();
if (resultPrice < 10000) {
// 특정 필드 에러가 아닌 글로벌 에러이므로 ObjectError로 담아줌
bindingResult.reject("totalPriceMin", new Object[]{10000, resultPrice}, null);
}
}
bindingResult.reject(errorCode, errorArgs, defaultMessage)
errorCode : 오류 코드
errorArgs : 오류 메시지의 파라미터를 치환하기 위한 값
defaultMessage : 오류 메시지를 찾을 수 없을 때 사용하는 기본 메시지
bindingResult.rejectValue(field, errorCode, errorArgs, defaultMessage)
field : 오류 필드명
errorCode : 오류 코드
errorArgs : 오류 메시지의 파라미터를 치환하기 위한 값
defaultMessage : 오류 메시지를 찾을 수 없을 때 사용하는 기본 메시지
errorCode는 앞서 codes와 달리 키값의 최상위 키워드만 명시되어 있는데, 이는 messageResolver에서 특정한 규칙을 이용해 키값을 생성하고, errors.properties에서 키값이 매칭되는 것이 있다면 그 값을 가지고 온다.
#추가
typeMismatch.java.lang.Integer=숫자를 입력해주세요.
typeMismatch=타입 오류입니다.
출처 : 김영한님의 스프링MVC 2편