はじめに
今までJSONパーサにGsonを使っていたのですが、あのJakeWharton氏曰く「Gson is deprecated.」との事だったので、Moshiを試してみました。
MoshiはSquare社が開発した軽量なJSONパーサで、Gsonの不満点を解消するために作られたそうです。
軽くGsonとの比較も行います。
導入
build.gradle
apply plugin: 'kotlin-kapt'
...
// Moshi
implementation 'com.squareup.moshi:moshi:1.9.2'
implementation 'com.squareup.moshi:moshi-kotlin:1.9.2'
kapt 'com.squareup.moshi:moshi-kotlin-codegen:1.9.2' // 1.9.Xからこれが無いと "Cannot serialize Kotlin type" エラーが発生する
// Retrofit
implementation "com.squareup.retrofit2:retrofit:2.7.0"
implementation "com.squareup.retrofit2:converter-moshi:2.7.0"
シリアライズ
Gson
data class Repos(
val id: Int,
val name: String,
// 変数名とJSONキーが一致しない場合は@SerializedNameアノテーションを付ける
@SerializedName("full_name") val fullName: String
)
Moshi
@JsonClass(generateAdapter = true) // Adapter化に必要
data class Repos(
val id: Int,
val name: String,
// 変数名とJSONキーが一致しない場合は@Jsonアノテーションを付ける
@Json(name = "full_name") val fullName: String
)
fromJSON
Gson
val jsonString = """
{
"id":1,
"name":"name",
"full_name":"fullName"
}
""".trimIndent()
val gson = Gson()
val repos = gson.fromJson(jsonString, Repos::class.java)
Moshi
val jsonString = """
{
"id":1,
"name":"name",
"full_name":"fullName"
}
""".trimIndent()
val adapter = Moshi.Builder().build().adapter(Repos::class.java)
val repos = adapter.fromJson(jsonText)
toJSON
Gson
val gson = Gson()
val repos = Repos(1, "name", "fullName")
val jsonString = gson.toJson(repos)
Moshi
val adapter = Moshi.Builder().build().adapter(Repos::class.java)
val repos = Repos(1, "name", "fullName")
val jsonString = adapter.toJson(repos)
Retrofitとの連携
Gson
private val gson = GsonBuilder()
.setLenient()
.create()
return Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
Moshi
private val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.build()
return Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addConverterFactory(MoshiConverterFactory.create(moshi))
.build()
パッと見ではGsonの方がコード量が少なく見えますが、Gsonはnon-nullな変数にnullを入れてしまう可能性があるという問題点があるようで、kotlinのnull安全を正しく利用しようとするならMoshiを使った方が安全なようです。
おわりに
今回の記事を書くにあたって以下のリンクを参考にさせて頂きました。
【Qiita】Kotlinと相性が良いMoshiのkotlin extensionを使う
【Qiita】Kotlin JSON (Moshi) 使い方