Spring Framework
Kotlin ObjectMapper 주의사항
Junuuu
2023. 11. 14. 00:01
728x90
개요
Kotlin에서는 직렬화 역직렬화를 위해 Jackson을 지원합니다.
의존성 추가
Maven
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
<version>2.15.3</version>
</dependency>
Gradle(Kotlin)
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.15.3")
테스트 클래스
data class Movie(
var name: String,
var studio: String,
var rating: Float? = 1f,
)
jacksonObjectMapper 테스트
@Test
fun `kotlin에서 지원하는 jacksonObjectMapper를 사용해보기`(){
val objectMapper = jacksonObjectMapper()
val movie = Movie("Endgame", "Marvel", 9.2f)
val serialized = objectMapper.writeValueAsString(movie)
val json = """
{"name":"Endgame","studio":"Marvel","rating":9.2}
""".trimIndent()
assertEquals(serialized, json)
}
@Test
fun `kotlin에서 지원하는 jacksonObjectMapper를 사용해보기 역직렬화`(){
val objectMapper = jacksonObjectMapper()
val serialized = """
{"name":"Endgame","studio":"Marvel","rating":9.2}
""".trimIndent()
val actual = objectMapper.readValue<Movie>(serialized)
assertEquals(9.2f, actual.rating)
}
jacksonObjectMapper를 활용하여 serialized를 수행할 수 있습니다.
jacksonObjectMapper 내부구조
fun jacksonObjectMapper(): ObjectMapper = jsonMapper { addModule(kotlinModule()) }
내부를 보면 kotlinModule이 추가된 것을 볼 수 있고 ObjectMapper가 반환됩니다.
ObjectMapper 테스트
@Test
fun `ObjectMapper를 사용해보기`(){
val objectMapper = ObjectMapper()
val serialized = """
{"name":"Endgame","studio":"Marvel","rating":9.2}
""".trimIndent()
val actual = objectMapper.readValue<Movie>(serialized)
assertEquals(9.2f, actual.rating)
}
// com.fasterxml.jackson.databind.exc.InvalidDefinitionException:
// Cannot construct instance of `cohttp://m.example.study.KotlinObjectMapperTest$Movie`
// (no Creators, like default constructor, exist): cannot deserialize from Object value
// no delegate- or property-based Creator)
InvalidDefinitionException이 발생합니다. 기본 생성자가 필요하다는 에러메시지입니다.
ObjectMapper에 kotlin 모듈을 추가하고 테스트
@Test
fun `ObjectMapper를 사용해보기`(){
val objectMapper = ObjectMapper()
objectMapper.registerModule(kotlinModule())
val serialized = """
{"name":"Endgame","studio":"Marvel","rating":9.2}
""".trimIndent()
val actual = objectMapper.readValue<Movie>(serialized)
assertEquals(9.2f, actual.rating)
}
kotlinModule을 추가하고 다시 테스트한다면?
잘 동작합니다.
주의할점
Spring 환경에서 ObjectMapper를 빈으로 등록하게 된다면 Global Bean으로 등록되어 위와 같은 InvalidDefinitionException 예외사항이 발생할 수 있습니다.
이런 경우 내가 작업한 범위 외에서 예외가 발생하기 때문에 원인에 대해 파악하기 힘들었습니다.
참고자료
https://www.baeldung.com/kotlin/jackson-kotlin