스프링 MVC 2편 - 백엔드 웹 개발 활용 기술 - (21) 검증 Validation - 오류 코드와 메시지 처리 2
인프런 스프링 MVC 2편 - 백엔드 웹 개발 활용 기술편을 학습하고 정리한 내용 입니다.
오류 코드와 메시지 처리 3
오류 코드를 만들 때 다음과 같이 자세히 만들 수도 있고, required.item.itemName : 상품 이름은 필수 입니다.range.item.price : 상품의 가격 범위 오류 입니다.
또는 다음과 같이 단순하게 만들 수도 있다.required : 필수 값 입니다.range : 범위 오류 입니다.
단순하게 만들면 범용성이 좋아서 여러 곳에서 사용 가능하지만, 메시지를 세밀하게 작성하기 어렵다.
반대로 너무 자세하게 만들면 범용성이 떨어진다.
가장 좋은 방법은 범용성으로 사용하다가, 세밀한게 필요할 때 새로 만들 수 있도록 메시지에 단계를 두는 방법이다.
예를 들어서 required라고 오류 코드를 사용한다고 가정해보자.
다음과 같이 required라는 메시지만 있으면 이 메시지를 선택해서 사용하는 것이다.
1
required: 필수 값 입니다.
그런데 오류 메시지에 required.item.itemName와 같이 객체명과 필드명을 조합한 세밀한 메시지 코드가 있다면
이 메시지를 높은 우선 순위로 사용하는 것이다.
1
2
3
4
5
#Level1
required.item.itemName: 상품 이름은 필수 입니다.
#Level2
required: 필수 값 입니다.
물론 이렇게 객체명과 필드명을 조합한 메시지가 있는지 확인하고, 없으면 범용 메시지를 선택할 수 있도록 추가 개발을 해야겠지만, 범용성 있게 잘 개발해두면, 메시지 추가 만으로 매우 편리하게 오류 메시지를 관리할 수 있을 것이다.
스프링은 MessageCodesResolver라는 것으로 이러한 기능을 지원한다.
오류 코드와 메시지 처리 4
MessageCodesResolver를 테스트 코드를 통해 이해해 보자.
validation/src/test/java/hello/itemservice/validation/MessageCodesResolverTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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");
}
}
첫 번째 테스트는

다음과 같이 required.item, required 이렇게 두 개가 나온다.
두 번째 필드 오류 테스트는
1
codesResolver.resolveMessageCodes("required", "item", "itemName", String.class);
이렇게 넣었으니
- required.item.itemName
- required.itemName
- required.java.lang.String
- required
이 조합과 순서로 나올 것 이다.

DefaultMessageCodesResolver가 만드는 규칙 같은 건데 알아보자.
MessageCodesResolver
- 검증 오류 코드로 메시지 코드들를 생성한다.
MessageCodesResolver는 인터페이스 이고,DefaultMessageCodesResolver는 기본 구현체이다.- 주로 다음과 함께 사용
ObjectError,FieldError
DefaultMessageCodesResolver의 기본 메시지 생성 규칙
객체 오류
1
2
3
4
5
6
7
객체 오류의 경우 다음 순서로 2가지 생성
1.: code + "." + object name
2.: code
예) 오류 코드: required, object name: item
1.: required.item
2.: required
필드 오류
1
2
3
4
5
6
7
8
9
10
11
필드 오류의 경우 다음 순서로 4가지 메시지 코드 생성
1.: code + "." + object name + "." + field
2.: code + "." + field
3.: code + "." + field type
4.: code
예) 오류 코드: typeMismatch, object name "user", field "age", field type: int
1. "typeMismatch.user.age"
2. "typeMismatch.age"
3. "typeMismatch.int"
4. "typeMismatch"
동작 방식
rejectValue(),reject()는 내부에서MessageCodesResolver를 사용한다. 여기에서 메시지 코드를생성함.FieldError,ObjectError의 생성자를 보면, 오류 코드를 하나가 아니라 여러 오류 코드를 가질 수 있다.MessageCodesResolver를 통해 생성된 순서대로 오류 코드 보관한다.

ObjectError 는 DefaultMessageSourceResolvable를 상속 받고 있다. (FieldError는 ObjectError를 상속 받음. )
FieldError : rejectValue("itemName", "required")
다음 4가지 오류 코드를 자동으로 생성
required.item.itemNamerequired.itemNamerequired.java.lang.Stringrequired
ObjectError : reject("totalPriceMin")
다음 2가지 오류 코드를 자동으로 생성
totalPriceMin.itemtotalPriceMin
오류 메시지 출력
타임리프 화면을 렌더링 할 때 th:errors가 실행된다. 만약 이 때 오류가 있다면 생성된 오류 메시지 코드를 순서대로 돌아가면서 메시지를 찾는다.
그리고 없으면 디폴트 메시지를 출력한다.
댓글남기기