오봉이와 함께하는 개발 블로그
스프링 MVC 2 - 오류 코드와 메시지 처리 part.3 본문
오류 코드와 메시지 처리 5
오류 코드 관리 전략
핵심은 구체적인 것에서 덜 구체적인 것으로 하는 것.MessageCodesResolver
는 required.item.itemName
처럼 구체적인 것을 먼저 만들어주고, required
처럼 덜 구체적인 것을 가장 나중에 만든다.
이렇게 하면 메시지 관련 공통 전략을 편리하게 도입할 수 있다.
왜 이렇게 복잡하게 사용..?
모든 오류 코드에 대해서 메시지를 각각 다 정의하면 개발자 입장에서 관리하기 너무 힘들다.
크게 중요하지 않은 메시지는 범용성 있는 requried
같은 메시지로 끝내고, 정말 중요한 메시지는 꼭 필요할 때 구체적으로 적어서 사용하는 방식이 더 효과적이다.
오류 코드 관리 전략 도입
errors.properties
#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} 까지 허용합니다.
크게 객체 오류와 필드 오류를 나누고 범용성에 따라 레벨을 나누었다.
itemName
의 경우 required
검증 오류 메시지가 발생하면 다음 순서로 메시지가 생성된다.
- required.item.itemName
- required.itemName
- required.java.lang.String
- required
이렇게 생성된 메시지 코드 기반으로 순서대로 MessageSource
에서 찾는다.
구체적인 것에서 덜 구체적인 순서대로 찾는다. 메시지에 1번이 없으면 2번을 찾고, 2번이 없으면 3번을 찾는다.
이렇게 되면 크게 중요하지 않은 오류 메시지는 기존에 정의한 것을 그냥 재활용할 수 있다.
실행
- Level1을 전부 주석
- Level2, 3을 전부 주석
- Lever4를 전부 주석 -> 못 맞츠면 코드에 작성한 디폴트 메시지를 사용
- Object 오류도 Level1, Level2로 재활용 가능
ValidationUtils
ValidationUtils 사용 전
if (!StringUtils.hasText(item.getItemName())) {
bindingResult.rejectValue("itemName", "required", "기본: 상품 이름은 필수입니다.");
}
ValidationUtils 사용 후
다음과 같이 한줄로 가능하다.
제공하는 기능은 Empty, 공백 같은 단순한 기능만 체크할 수 있다.
ValidationUtils.rejectIfEmptyOrWhitespace(bindingResult, "itemName", "required");
정리
- rejectValue() 호출
- MessageCodesResolver를 사용해서 검증 오류 코드로 메시지 코드들을 생성
- new FieldError()를 생성하면서 메시지 코드들을 보관
- th:errors에서 메시지 코드들로 메시지를 순서대로 메시지에서 찾고 노출
오류 코드와 메시지 처리 6
스프링이 직접 만든 오류 메시지 처리
검증 오류 두 가지로 나눌 수 있다.
- 개발자가 직접 작성한 오류 코드 -> rejcetValue()를 직접 호출
- 스프링이 직접 검증 오류에 추가한 경우(주로 타입 정보가 맞지 않을 때)
price
필드에 문자를 입력하고 로그를 확인하면 BindingResult
에 FieldError
가 담겨있고, 다음과 같은 메시지 코드들이 생성된다
codes[typeMismatch.item.price,typeMismatch.price,typeMismatch.java.lang.Integer,typeMismatch]
4가지 메시지 코드가 입력되어 있다.
- typeMismatch.item.price
- typeMismatch.price
- typeMismatch.java.lang.Integer
- typeMismatch
스프링은 타입 오류가 발생하면 typeMismatch
라는 오류 코드를 사용한다.
이 오류 코드가 MessageCodesResolver 를 통하면서 4가지 메시지 코드가 생성된 것이다.
아직 errors.properties
에 메시지 코드가 없기 때문에 스프링이 생성한 기본 메시지가 출력된다.
Failed to convert property value of type java.lang.String to required type java.lang.Integer for property price; nested exception is java.lang.NumberFormatException: For input string: "A"
error.properties
에 다음 내용을 추가하자
#추가
typeMismatch.java.lang.Integer=숫자를 입력해주세요.
typeMismatch=타입 오류입니다.
다시 실행하면 소스코드를 하나도 건들지 않고, 원하는 메시지를 단계별로 설정할 수 있다.
현재 코드에서 타입 오류를 발생시키면 타입에 대한 오류(숫자칸에 문자 입력)와 지정한 조건(1,000 ~ 1,000,000)에 대한 오류 메시지가 뜬다.
타입에 대한 오류가 있을 때 타입 오류만 알려주고 싶으면 아래 코드를 최상단에 추가하자
if(bindingResult.hasErrors()) {
log.info("errors = {}", bindingResult);
return "validation/v2/addForm";
}
출처 : 인프런 김영한 지식공유자님 강의 스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
'BE > Spring' 카테고리의 다른 글
스프링 MVC 2 - Bean Validation 소개, 시작 (0) | 2022.08.24 |
---|---|
스프링 MVC 2 - Validator 분리 (0) | 2022.08.23 |
스프링 MVC 2 - 오류 코드와 메시지 처리 part.2 (0) | 2022.08.23 |
스프링 MVC 2 - 오류 코드와 메시지 처리 part.1 (0) | 2022.08.23 |
스프링 MVC 2 - FieldError, ObjectError (0) | 2022.08.23 |