본문 바로가기
Spring

[Spring] jackson String "00": not one of the values accepted 에러 해결책

by 노력남자 2023. 11. 15.
반응형

문제

 

Spring Boot 버전 업한 후 테스트를 돌리던 중 @JsonValue를 붙여놓은 enum으로 역직렬화되는 코드에서 "jackson String "00": not one of the values accepted" 에러가 발생했다.

 

아래 코드를 보며 자세히 알아보자.

 

역직렬화할 json은 아래와 같았다.

 

userType은 문자열 타입이다.

 

{
    "userType": "00"
}

 

위 json을 역직렬화할 UserType의 code의 타입은 Int다. (enum에서 @JsonValue를 사용하면 직렬화, 역직렬화 둘 다에 사용된다.)

 

class User(
    val userType: UserType
) {

    enum class UserType(
        @JsonValue val code: Int
    ) {
        NORMAL(0),
        ADMIN(1);
    }
}

 

"00" 이든, "000" 이든 Int로 잘 맵핑해줬었는데 jackson 버전이 올라가면서 이를 지원 안 해주기로 했는지 "00"은 Int가 아니라 역직렬화가 불가능하다 라는 에러가 발생했다.

 

 

@Test
fun testJsonValue() {
    val objectMapper = ObjectMapper().registerKotlinModule()
    val json = """
        {
            "userType": "00"
        }            
    """.trimIndent()

    assertEquals(User.UserType.NORMAL, objectMapper.readValue<User>(json).userType)
}

 

원인 

 

jackson-databind 2.13.0부터 안 된다.

 

바뀐 이유는 모르겠다.

 

해결책

 

1. 그냥 enum에 @JsonValue가 붙어있는 필드의 타입을 String으로 바꾸자.

 

2. 굳이 써야 한다면... @JsonCreator를 이용하자.

 

class User(
    val userType: UserType
) {

    enum class UserType(
        @JsonValue val code: Int
    ) {
        NORMAL(0),
        ADMIN(1);

        companion object {
            @JsonCreator(mode = JsonCreator.Mode.DELEGATING)
            @JvmStatic
            fun from(
                code: String
            ): UserType {
                return UserType.values().first { it.code == code.toInt() }
            }
        }
    }
}
반응형

댓글