Spring

검증1 - Validation : 오류 코드와 메시지 처리1~6

sami355 2022. 8. 26. 01:16

BindingResult 가 제공하는 rejectValue() , reject() 를 사용하면 FieldError , ObjectError 를 직접 생성하지 않고, 깔끔하게 검증 오류를 다룰 수 있다.

인프런 김영한님의 스프링mvc2편을 보고 정리한 글입니다.

무엇을 배웠나요?

오류 코드와 메시지 처리1

FieldError는 두가지 생성자를 제공한다.

public FieldError(String objectName, String field, String defaultMessage); 
public FieldError(String objectName, String field, @Nullable Object rejectedValue, boolean bindingFailure, @Nullable String[] codes, @Nullable Object[] arguments, @Nullable String defaultMessage)
  • FieldError의 파리미터 목록
    • objectName: 오류가 발생한 객체 이름
    • field : 오류 필드
    • rejectedValue: 사용자가 입력한 값(거절된 값)
    • bindingFailure: 타입 오류 같은 바인딩 실패인지, 검증 실패인지 구분 값
    • codes : 메시지 코드
    • arguments : 메시지에서 사용하는 인자
    • defaultMessage : 기본 오류 메시지
  • 스프링 부트 메시지 설정 추가
spring.messages.basename=messages,errors

 

  • errors.properties 추가
required.item.itemName=상품 이름은 필수입니다. 
range.item.price=가격은 {0} ~ {1} 까지 허용합니다. 
max.item.quantity=수량은 최대 {0} 까지 허용합니다. 
totalPriceMin=가격 * 수량의 합은 {0}원 이상이어야 합니다. 현재 값 = {1}
  • errors_en.properties파일을 생성하면 오류 메시지도 국제화 처리를 할 수 있다

오류 코드와 메시지 처리2

  • BindingResult가 제공하는 rejectValue() , reject() 를 사용하면 FieldError , ObjectError를 직접 생성하지 않고, 깔끔하게 검증 오류를 다룰 수 있다.
  • 사용 예시
if (item.getPrice() == null || item.getPrice() < 1000 || item.getPrice() >1000000) { 
	bindingResult.rejectValue("price", "range", new Object[]{1000,1000000}, null);
}

오류 코드와 메시지 처리3

  • 오류코드를 만들 때 다음과 같이 자세히 만들거나 단순하게 만들 수 있다.
<!--> 자세하게 만드는 경우 <--> 
	required.item.itemName: 상품 이름은 필수 입니다.
    
<!--> 단순하게 만드는 경우 <--> 
	required: 필수 값입니다.
  • 단순하게 만들면 범용성이 좋아서 여러곳에서 사용할 수 있지만, 메시지를 세밀하게 작성하기 어렵다. 반대로 너무 자세하게 만들면 범용성이 떨어진다. 가장 좋은 방법은 범용성으로 사용하다가, 세밀하게 작성해야 하는 경우에는 세밀한 내용이 적용되도록 메시지에 단계를 두는 방법이다
  • 예를 들어 위와 같은 경우에는 자세하게 만들수록 높은 우선순위를 가진다.
  • 스프링은 MessageCodesResolver라는 것으로 이러한 기능을 지원한다.

오류 코드와 메시지 처리4

  • MessageCodesResolver
    • 검증 오류 코드로 메시지 코드들을 생성한다.
    • MessageCodesResolver인터페이스이고 DefaultMessageCodesResolver는 기본 구현체이다.
    • 주로 다음과 함께 사용 ObjectError , FieldError
  • DefaultMessageCodesResolver 의 기본 메시지 생성 규칙

객체오류인 경우

객체 오류의 경우 다음 순서로 2가지 생성
: code + "." + object name
: code

예) 오류 코드: required, object name: item
required.item
required

필드 오류인 경우

필드 오류의 경우 다음 순서로 4가지 메시지 코드 생성
code + "." + object name + "." + field
code + "." + field
code + "." + field type
code

예) 오류 코드: typeMismatch, object name "user", field "age", field type: int
"typeMismatch.user.age"
"typeMismatch.age"
"typeMismatch.int"
"typeMismatch" </aside>

 


오류 코드와 메시지 처리5

  • 추가로 ValidationUtils 이라는 것도 존재한다.

오류 코드와 메시지 처리6

  • 만약 정수형 변수에 문자열을 넣으려고 한다면 다음과 같은 오류가 난다.

  • 해당 오류같은 경우 로그를 찍어보면 스프링이 생성해주는 에러 코드의 경우 다음과 같다
codes [typeMismatch.item.quantity,typeMismatch.quantity,typeMismatch.java.lang.Integer,typeMismatch];
  • 다음과 같은 경우에서 해결방법은 간단하다. errors.properties에 스프링이 만들어주는 에러코드를 따로 추가해주면 된다.

더 필요하다고 생각한 것이 있나요?

  • 객체 오류와 필드 오류에 대한 것이 헷갈리는듯 하다.
    • 필드 오류는 해당 필드 하나에서 검증하는 로직이고 객체 오류는 그외의 오류를 말하는 듯 하다. 예를 들어 필드 두개를 조합해서 검증시 발생하는 오류는 객체 오류에 해당하며 타입이 달라서 생기는 오류 역시 필드오류에 해당한다.