직렬화와 역직렬화
통신에서는 객체 그 자체를 통신에 사용하기가 어렵다. 때문에 컴퓨터에서는 파일을 다른 컴퓨터로 보내기 전 통신이 가능하면서 나중에 재구성할 수 있는 포맷으로 변환해주어야 한다. 우리는 이러한 과정을 직렬화라고 한다. 이렇게 변환된 포멧의 일종이 바로 JSON이다.
직렬화된 파일은 다시 객체 형태로 변환되어야 하는데 이러한 과정을 바로 역직렬화라고 한다.
Moshi란?
Moshi란 JSON과 객체 사이의 직렬화와 역직렬화를 쉽고 안전하게 할 수 있도록 돕는 라이브러리이다.
Moshi의 특징으로는 리플랙션과 Codegen 방식의 변환을 모두 지원한다는 점이다. 이러한 방식으로
자 이제 Moshi를 이용해 JSON을 어떻게 역직렬화 하는지 살펴보자
Moshi Annotation에 JSON 구성 요소를 대응시키기
Moshi를 사용하기 위해서는 먼저 어떻게 JSON의 구조에 맞춰 Moshi Annotation들을 대응시켜야 하는지 알아야 한다.
Moshi에서 JSON 구조에 대해 사용할 수 있는 Annotation은 두가지이다.
- @JsonClass(generateAdapter = true)
- @field:Json(name = "[JSON 키]")
@JsonClass : JSON Object
@JsonClass는 JSON Object에 대응되는 역할을 한다. 따라서 @JsonClass는 JSON Object에 대응되는 class를 만들 때 그 위에 붙인다. <그림1>의 JsonClass는 다음과 같이 표현 가능하다.
@JsonClass(generateAdapter = true)
data class PokemonList()
@JsonClass 에는 파라미터로 generateAdapter가 있는데 이것을 true로 해주어야 codegen 방식으로 직렬화, 역직렬화가 가능해진다.
@field:Json : JSON key-value
@field:Json은 JSON 내부의 Key-Value 값에 붙인다. @field:Json은 name이라는 파라미터를 가지는데 이 파라미터는 json 포멧의 key값에 대응되도록 만들어야 한다. <그림1>의 key-value 쌍들은 다음과 같이 표현 가능하다.
@JsonClass(generateAdapter = true)
data class PokemonList(
@field:Json(name = "count") val count: Int,
@field:Json(name = "next") val next: String,
@field:Json(name = "previous") val previous: String
)
마지막 results 필드는 추후에 JsonArray를 다루는 방법을 배우면서 작성한다.
List<JsonClass> : JSON Array
마지막은 JSON Array이다. JSON Array는 JSON Object의 집합이다. 따라서 이는 별도의 Annotation 없이 다음 코드의 마지막줄과 같이 표현된다.
@JsonClass(generateAdapter = true)
data class PokemonList(
@field:Json(name = "count") val count: Int,
@field:Json(name = "next") val next: String,
@field:Json(name = "previous") val previous: String
@field:Json(name = "results") val results: List<Pokemon>
)
물론 Pokemon은 @JsonClass로 선언되어있어야 한다.
@JsonClass(generateAdapter = true)
data class Pokemon()
정리
이번 글에서는 Moshi Annotation에 JSON의 구성요소를 대응시키는 방법을 알아보았다. 다음 글에서는 이를 이용해 어떻게 직렬화와 역직렬화를 하는지 알아보자.