하지만 오늘 제가 알아온 것은 kotlinx-serialization(이하 “코시”)입니다.
코시는 무슨 장점이 있을까요?
우선 아래 코드를 봐주십시옹
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
const val JSON_TEXT = """
{
"name": "Seoul"
}
"""
@Serializable
data class ErrorExam(
val name: String,
val address: String = "Seoul"
)
fun main() {
//Gson
val token = object : TypeToken<ErrorExam>() {}.type
val objectFromGson = Gson().fromJson<ErrorExam>(JSON_TEXT, token)
println(objectFromGson)
//Gson으로 사용하게 되면 address에 값은 null이 나온다.
//kotlinx-serialization
val objectFromKotilnxSerialization: ErrorExam =
Json.decodeFromString(JSON_TEXT)
// Json { coerceInputValues = true }.decodeFromString(JSON_TEXT)
println(objectFromKotilnxSerialization)
//하지만 kotlinx-serialization을 사용하면 address 값은 Seoul이 나오는 것을 볼 수 있다.
}
기존 Gson에서 역직렬화를 했을때 문제점은
data 클래스의 프로퍼티가 널러블/논 널러블 타입을 명확히 보장해주지 못했다.
하지만,
코시는 이 타입을 보장해주고 있다.
그렇다고 디폴트 밸류가 우선 값이 아니다. 서버로 부터 받은
응답값을 더 우선시 한다.
반응형
예제에서 address가 “Seoul” 값을 가지고 있어도, 서버에서 “Busan”이라는 값이 들어오면,
“Busan”이 출력되는 것입니다.
타입을 보장해주고 있어서, non_null에 null이 들어오게 되면 바로 에러를 뱉습니다.
이 부분이 Gson과 차이점이 있습니다.
코시는 이러한 에러를Json { coerceInputValues = true }.decodeFromString(JSON_TEXT)다음과 같은 옵션으로 설정하게 되면 기본값으로 설정한 문자열이 반환됩니다.
만약 {"name":”수열”,"address":"Seoul","age":1} 같이 모델에 없는 키 값이 들어오면 이 역시 에러가 생기는데 이를 무시하려면 ignoreUnknownKeys = true 이 옵션을 사용하시면 됩니다.
서버에 값을 요청할 때와 응답 받을 때 디폴트 밸류를 처리하는 법이 각각 다르다.
요청할 때 → 디폴트 값이 보내지지 않는다.
data class ErrorExam(
val name: String,
val address: String = "Seoul"
)
예를 들어 ErrorExam(”수열”)으로 보내면 {”name”: “수열”} 이런식으로 이름만 보내는 셈이다.
이런 경우에는encodeDefaults = true옵션을 사용하면 기본값도 같이 보내진다.
응답할 때 → 디폴트 값이 받아진다.
{”name”: “수열”} 이렇게만 서버에서 받아도 ErrorExam(”수열”, “Seoul”)로 받아지는 것이다.
마지막으로 간단한 사용법 예제를 보고 마무리 해보자.
@Serializable
data class Data(val a: Int,val b: String)
fun main() {
//직렬화 객체를 -> Json
val json = Json.encodeToString(UseExam(42, "str"))
println(json)
//역직렬화 Json -> 객체
val obj = Json.decodeFromString<UseExam>("""{"a":42, "b": "str"}""")
print(obj)
}