[Spring] 오류 코드와 메시지 처리

JJoSuk·2023년 6월 8일
0

본 프로젝트 자료는 김영한님의 스프링 MVC 2편 - 백엔드 웹 개발 활용 기술을 참고 제작됐음을 알립니다.

오류 메시지와 메시지 처리(1)

FieldError 생성자

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

objectName : 오류가 발생한 객체 이름
field : 오류 필드
rejectedValue : 사용자가 입력한 값(거절된 값)
bindingFailure : 타입 오류 같은 바인딩 실패인지, 검증 실패인지 구분 값 codes : 메시지 코드
arguments : 메시지에서 사용하는 인자
defaultMessage : 기본 오류 메시지

  • FieldError , ObjectError 의 생성자는 codes , arguments 를 제공한다. 이것은 오류 발생시 오류 코드로 메시지를 찾기 위해 사용된다.

위와 같이 defaultMessage 로 메시지를 출력할 수 있지만, 오류 메시지만 따로 모아 처리하는게 효율적이다.


errors 메시지 파일 생성

예제로 errors.properties 파일을 만들어 오류 메시지를 관리해보도록 하자.

추가하기 앞서 스프링 부트가 errors.properties 파일을 인식할 수 있게 작업을 해야 한다.

스프링 부트 메시지 설정 추가
application.properties

application.properties 에 코드르 추가해주면 messages 와 errors 파일을 같이 인식하게 된다.

errors.properties 파일 생성

  • errors_en.properties 파일을 추가로 만들어 주면 국제화 메시지 처리도 같이 할 수 있게 된다.

이제 errors 에 등록된 메시지를 사용하도록 코드 수정

defaultMessage 의 오류 메시지는 이제 필요없으니 제거 해주고, 메시지는 new String 에 넣어주고, 오브젝트는 new Object 에 값을 넣어 수정해주면 관리에 유용하다.


오류 코드와 메시지 처리2

2의 목표는 FieldError , ObjectError 의 번거로운걸 반복하지 않게 자동화를 해볼려고 한다.

indingResult 는 이미 본인이 검증해야 할 객체인 target 을 알고 있다고 한다.

로그를 입력해보고 출력해보니,

알고있구나...

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

bindingResult.addError(new FieldError(
	"item", 
	"quantity",
    item.getQuantity(), 
    false, 
    new String[{"max.item.quantity"}, 
  	new Object[]{9999}, 
    null));

위 코드를

현재 코드처럼 보기 편하게 정리 할 수 있다. 원리는,

다음과 같이

  • field : 오류 필드명
  • errorCode : 오류 코드(이 오류 코드는 메시지에 등록된 코드가 아니다. 뒤에서 설명할 messageResolver를 위한 오류 코드이다.)
  • errorArgs : 오류 메시지에서 {0} 을 치환하기 위한 값
  • defaultMessage : 오류 메시지를 찾을 수 없을 때 사용하는 기본 메시지

BindingResult 는 타겟이 어떤 정보를 갖고 있는데 알고 있어서, 아이템에 대한 정보는 없어도 된다.

  • 오류 필드명 price 그대로 사용

오류 코드와 메시지 처리3

오류 코드는 다음과 같이 자세히 만들 수 있고

  • required.item.itemName : 상품 이름은 필수 입니다.

다음과 같이 단순하게 만들 수 있다.

  • required : 필수 값 입니다.

단순하게 만들면 범용성 있게 여러 장소에서 사용할 수 있으나 메시지가 세밀하지 못해 사용자가 불편할 수 있으며,

세밀하게 만들면 범용성은 떨어지나 메시지가 자세히 내용을 설명해줘 사용자가 인지하는데 어려움이 없다.

둘 중에 하나만 선택해서 사용하지말고 둘 다 활용해보자.

우선 테스트 코드로 실험해보고자 한다.

위와 같은 방법으로 만들었을 경우 2가지 오류 코드를 사용할 수 있다.

위와 같은 벙법으로 만들면 4가지가 생성된다.

동작방식

  • rejectValue() , reject() 는 내부에서 MessageCodesResolver 를 사용한다. 여기에서 메시지 코드들을 생성한다.
  • FieldError , ObjectError 의 생성자를 보면, 오류 코드를 하나가 아니라 여러 오류 코드를 가질 수 있다. MessageCodesResolver 를 통해서 생성된 순서대로 오류 코드를 보관한다.
  • 타임리프 화면을 렌더링 할 때 th:errors 가 실행된다. 만약 이때 오류가 있다면 생성된 오류 메시지 코드를 순서대로 돌아가면서 메시지를 찾는다. 그리고 없으면 디폴트 메시지를 출력한다.

오류 코드와 메시지 처리4

오류 코드 작성 순서는 구체적인걸 우선으로 만들고 덜 구체적이면 뒷 순위로 밀면 된다.

크게 중요하지 않은 메시지는 범용성 있는 requried 같은 메시지로 끝내고, 정말 중요한 메시지는 구체적으로 작성해 단계별 로 만드는걸 추천한다.

예제 코드

이미 단계별로 만들어진게 있어 이걸 활용해 에러 코드를 만들어 볼려고 한다.

itemName 의 경우 required 검증 오류 메시지가 발생하면 다음 코드 순서대로 메시지가 생성된다.

  1. required.item.itemName
  2. required.itemName
  3. required.java.lang.String
  4. required

에러.프로퍼티스

레벨로 단계를 적했다.

1레벨

실행 화면

2단계 필요없어 스킾

3레벨

실행화면

4레벨

실행화면


오류 코드와 메시지 처리6

*가격에는 Integer 로 설정되어 있어 문자를 넣을 경우 위와 같은 오류 메시지가 출력되는데, 저 메시지 같은 경우 직접 등록한게 아니라 스프링 자체에서 만든 메시지를 보여주는 거다.

6의 목표는 저 메시지를 지우는 방법을 배우고자 한다.

오류를 출력했을 때,

run 코드로 친절하게 저 이유 때문에 생성할 수 없어 오류 메시지를 출력했다고 알려준다.

  • 저기에 정답이 있다.
  • typeMismatch.item.price,typeMismatch.price,typeMismatch.java.lang.Integer,typeMismatch
  • 이 코드를 활용해서 메시지를 변경해보자.

에러.프로퍼티스

에러.프로퍼티스 파일로 들어가 고대로 문자를 복사하고 원하는 것을 추려서 출력하고 싶은 메시지를 입력하면 끝난다.

실행 결과


추가*

만약 메시지 출력을 간결하게 한 줄로 하고 싶다면,

코드를 추가해 안나오게 막으면 된다.

실행 결과

끝!

profile
안녕하세요

0개의 댓글