kotlinx.serialization
jet brains 발표
블로그 포스트
블로그 포스트
일단 간단하고 핵심적인 내용만 훑어봤다.
Kotlin을 쓰면서 JSON (역)직렬화를 한다면 Jackson / Gson / Moshi 셋 중 하나를 쓰고 있었을 것이다.
Kotlin은 Java랑 100% 호환성이 있다고 하지만, 이 라이브러리들은 주의없이 사용하면 예상치 못한 결과를 볼 수 있다.
안드로이드가 자바기반이라 커스텀 뷰 생성자를 default 값으로 한번에 만들 때 @JvmOverloads
를 붙여주듯이 신경 써줄 부분이 있다.
data class User(
val name: String,
val email: String,
val age: Int = 13,
val role: Role = Role.Viewer
)
enum class Role { Viewer, Editor, Owner }
val user = Gson().fromJson(jsonString, User::class.java)
{
"name" : "John Doe",
"email" : "john.doe@email.com"
}
age
는 defualt value를 무시하고 0이 되며, role
은 아예 null이 되어 앱이 터져버린다.@Serializable // Annotation 추가
data class User(
val name: String,
val email: String,
val age: Int = 13,
val role: Role = Role.Viewer
)
enum class Role { Viewer, Editor, Owner }
val user = Json.parse(User.serializer(), jsonString)
@Serializable
sealed class Message {
abstract val content: String
}
@Serializable
data class BroadcastMessage(override val content: String) : Message()
@Serializable
data class DirectMessage(override val content: String, val recipient: String) : Message()
val data: List<Message> = listOf(
DirectMessage("Hey, Joe!", "Joe"),
BroadcastMessage("Hey, all!")
)
val string = Json.encodeToString(data)
println(string)
// [{"type":"DirectMessage","content":"Hey, Joe!","recipient":"Joe"},{"type":"BroadcastMessage","content":"Hey, all!"}]
val obj = Json.decodeFromString<List<Message>>(string)
println(obj)
// [DirectMessage(content=Hey, Joe!, recipient=Joe), BroadcastMessage(content=Hey, all!)]
type
)해서 직렬화한다.type
필드를 이용해서 원래 타입으로 역직렬화된다.addConverterFactory()
로 손쉽게 추가할 수 있다. (Jake Wharton)
moshi 사용하면서 테스트코드를 작성해보았습니다. default value가 적용이 되는데 혹시 어떤 resource를 보고 default value가 적용이 안된다고 하셨는지 궁급합니다!