출처 핀터레스트
네트워크 통신 즉, 하나의 컴퓨터에서 다른 컴퓨터로 객체를 보낼때 그 자체를 보내는데에는 어려움이 있다.
보낼 객체가 통신이 가능하게 변환해 주어야 하는데 우리는 이러한 작업을 직렬화라고 하고,
이렇게 받은 직렬화된 파일을 다시 객체로 변환해주는 것을 역 직렬화라고 한다.
직렬화에는 여러 종류가 있다.
첫 번째는 gson이다.
간단하게 장점이라면,
- Json으로 또는 그 반대로 변환 가능한 간단한 메서드인, toJson() 와 fromJson()를 제공
등이 있다.
두번째는 moshi 이다.
moshi 같은 경우는 Gson이 하지 않는 몇 가지를 최적화 한다고 합니다.
- @HexColor int와 같은 한정자는 단일 Java 유형에 대해 여러 Json 표현을 허용한다고 합니다.
이밖에도 많이 있지만, 간단히 두개만 적겠습니다.
참고
https://stackoverflow.com/questions/43577623/moshi-vs-gson-in-android
Moshi vs Gson in android
I'm deciding on whether to use Moshi by square or Gson to serialize and deserialize model data. one thing i always did not like about Gson is i think it uses reflection which can be slow on and...
stackoverflow.com
하지만 오늘 제가 알아온 것은 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() {
val token = object : TypeToken<ErrorExam>() {}.type
val objectFromGson = Gson().fromJson<ErrorExam>(JSON_TEXT, token)
println(objectFromGson)
val objectFromKotilnxSerialization: ErrorExam =
Json.decodeFromString(JSON_TEXT)
println(objectFromKotilnxSerialization)
}
기존 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() {
val json = Json.encodeToString(UseExam(42, "str"))
println(json)
val obj = Json.decodeFromString<UseExam>("""{"a":42, "b": "str"}""")
print(obj)
}
각 직렬화와 역직렬화 하는 법은 간단하게 다음과 같이 실행하면 된다.