티스토리 뷰

현재 SpringBoot 스터디를 하는 와중에 Enum이 포함되어 있는 Dto로 Controller에서 RequestBody로 값을 받는데 Enum에 없는 값을 RequestBody에 입력했을 때 위와 같은 에러가 발생했다.

 

 

JSON parse error가 발생하는 이유

예를 들어 아래와 같은 Enum를 사용한다고 하자.

public enum Test {
	TEST_A,
    	TEST_B
    	TEST_C
    	TEST_D
    	;
 }

 

위와 같은 enum를 사용할 경우 RequstBody로 'TEST_A'를 받으면 자동적으로 enum에서 TEST_A랑 같다고 매칭시켜 TEST_A를 반환한다.

하지만, 만일 위에 없는 값인 'TEST_E'가 들어올 경우? json으로 받은 값이랑 매칭 시킬 enum이 없어서 'JSON parse error'가 발생한다.

발생한 'JSON parse error'의 에러 메시지의 뒷 부분을 보면 'not one of the values accepted for Enum class'라는 에러 메시지가 있다. 즉 적합한 값이 enum class 내에 없다는 것이다. 

 

enum class 내에 매칭되는 값이 없으므로 Controller에서 json 형태로 받을 때 JSON parse error가 발생하는 것이다.

 

 

Enum 매칭되지 않는 값이 들어왔을 JSON parse error 처리

Enum에 매칭되지 않는 값이 들어왔을 경우에는 위와 같이 JSON parse error가 발생하면서 400번 'Bad Request'를 반환한다. 이 부분에 대해 클라이언트에서 별도 처리를 해줘도 되지만 Enum와 일치하지 않는 값이 들어왔을 경우에도 백엔드에서 'JSON parse error' 없이 로직을 처리하고 싶다면, enum class 내에서 별도 'JsonCreator'를 정의해서 JSON으로 받은 값을 처리해주는 별도 함수를 생성해 그 안에서 매칭되지 않는 값에 대한 처리를 해주면 된다.

이 처리를 위해서는 @JsonCreator 어노테이션을 사용한다. (com.fasterxml.jackson.annotation.JsonCreator)

@JsonCreator 어노테이션을 사용할 메소드의 경우 외부에서 접근가능하고 enum을 생성하지 않아도 사용 가능해야하므로 'public static'으로 생성해야한다.

 

위 어노테이션을 사용해서 받은 String value 값이 enum안에 있는지 없는지 체크하고 없을 경우 null 반환 또는 따로 기본 Exception 또는 CustomException을 생성해 Excpetion을 발생시키면 된다.

 

 

1. for 문을 이용한 체크

enum 안에 해당 값이 있는지 체크하는데 가장 많이 사용하는 방법이다. (물론 해당 함수는 enum 내에 위치해야한다.)

@JsonCreator
public static TestEnum getEnumFromValue(String value) {
	for(TestEnum enum : values()) {
    		if(enum.name().equals(value)) {
        		return enum;
       	 	}
    	}
   	return null;
}

 

for문 안에서 'values()'를 호출해 enum의 모든 값을 enum 하나로 가져오고 그것의 name() 즉, enum의 value 값을 가져와 일치할 경우 enum를 return하고 끝까지 일치 하지 않을 경우 null을 return 하는 것이다.

return null하는 부분에 'throw new Exception("enum 값이 일치 하지 않습니다.")' 라는 식으로 아예 Exception을 던져도 된다. 대신 그럴 경우 String으로 들어온 value를 Enum으로 변경하는 함수인 'getEnumFromValue()'에 아래와 같이 throws Exception을 붙여줘야 한다.

 

 

2. valueOf()와 try-catch를 이용한 체크

enum에 기본으로 제공해주는 함수에 아예 값이 있는지 없는지 체크할 수 있는 함수는 없을지 enum의 함수를 살펴 보던 중 valueOf()라는 함수가 있는 것을 발견했다. 보통 다른 class들의 valueOf()의 경우 값이 없을 경우 null을 반환한다던지 하는 것이 있던 것 같아서 enum의 valueOf()로도 테스트를 해봤지만 enum의 valueOf()는 값이 존재하지 않을 경우 마찬가지로 알맞은 enum value가 없다면서 JSON parse error를 반환시킨다. 그래서 사용하지 말까... 생각하다가 여기에 try-catch를 입혀서 위와 마찬가지로 값이 맞지 않을 경우 null을 return 할 수 있겠다는 생각이 들었다.

 

@JsonCreator
public static TestEnum getEnumFromValue(String value) {
	try {
          	return TestEnum.valueOf(value);
     	 } catch (Exception e) {
          	return null;
     	 }
}

 

결과는 성공이었다!! for문을 사용한 것과 코드 줄 수는 차이가 없지만 그래도 뭔가 좀 더 간결해진 느낌이었다.

catch문에 잡히는 Exception의 종류는 IllegalArgumentException으로 enum에 매칭되는 해당 값이 없을 경우 발생하는 Exception이다.

 

 

위의 방법들로 해당 enum에 있는 값인지 아닌지 체크를 하고 null 값을 반환해줄 경우 더 이상 enum에 없는 값이 들어와도 JSON parse erro가 발생하지 않고 null 값이 들어가진다. 이 null 값으로 백엔드에서 별도의 필요한 처리를 해주면 된다.

 

 

 

 

enum는 진짜 진짜 오랜만에 사용해서 이번에 사용하는데 조금 삽질도 많이 했고 재미도 많이 봤다. 사용해보면서 현재 회사에서 하고 있는 프로젝트에서 Constant로 빼놓은 것들을 Enum로 바꿔서 사용하면 좀 더 편하지 않았을까 하는 후회도 들었다.

앞으로 enum에 대해 많이 사용해보고 공부도 많이 해봐야겠다.

 

 

 

 

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함