달달한 스토리

728x90
반응형

출처 핀터레스트

 

네트워크 통신 즉, 하나의 컴퓨터에서 다른 컴퓨터로 객체를 보낼때 그 자체를 보내는데에는 어려움이 있다.

 

보낼 객체가 통신이 가능하게 변환해 주어야 하는데 우리는 이러한 작업을 직렬화라고 하고,

이렇게 받은 직렬화된 파일을 다시 객체로 변환해주는 것을 역 직렬화라고 한다.

 

직렬화에는 여러 종류가 있다.

첫 번째는 gson이다.

 

간단하게 장점이라면,

 

  • Json으로 또는 그 반대로 변환 가능한 간단한 메서드인, toJson() 와 fromJson()를 제공

 

  • Java Generics의 광범위한 지원

 

  • 개체에 대한 사용자 지정 표현 허용

 

등이 있다.

 

두번째는 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() {
    //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)
}

 

각 직렬화와 역직렬화 하는 법은 간단하게 다음과 같이 실행하면 된다.

728x90
반응형

공유하기

facebook twitter kakaoTalk kakaostory naver band
loading