LoginSignup
23
18

More than 3 years have passed since last update.

【Kotlin】kotlinx.serializationを使ってjson parseをやってみる

Last updated at Posted at 2020-03-09

kotlinx.serializationとは

Kotlin serialization consists of a compiler plugin, that generates visitor code for serializable classes, runtime library with core serialization API and JSON format, and support libraries with ProtoBuf, CBOR and properties formats.

Serialize可能なクラスのvisitor codeを生成するコンパイラプラグインとcore serialization APIおよびJSON形式のランタイムライブラリで構成している。

つまり、Kotlinで作られたSerializerということですね。

また、そのほかの特徴としては

・Supports Kotlin classes marked as @Serializable and standard collections.
・Provides JSON, CBOR, and Protobuf formats.
・Complete multiplatform support: JVM, JS and Native.

など挙げられており、KotlinでのMultiplatform開発では特に活躍しそうです。
また、二つ目にあるformat以外にもv0.2.0から HOCON なども追加されたようです。

その他対応format一覧
https://github.com/Kotlin/kotlinx.serialization/blob/master/formats/README.md

Androidでは似たようなJson parserにGson、Jackson、Moshi、kotshiなどがあります。

v0.2.0

2020/03/10現在のlatest versionはv0.2.0となります。
そのため導入した際には都度更新差分を早めにキャッチアップすることをおすすめします。

導入方法

Androidを例にして導入していきます。

gradle

まずはproject rootのbuild.gradleにコンパイラプラグインを追加します。

build.gradle

buildscript {
    ext.kotlin_version = "1.3.70" // 1

    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
    }
}
  1. 最低でもv1.3.30以上には指定する必要があります。

次に利用するmoduleのbuild.gradleにランタイムライブラリを追記します。

build.gradle
repositories {
    jcenter()
}

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" // or "kotlin-stdlib-jdk8"
    implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.20.0"
}

また、Kotlin DSLで記述すると下記になります。

build.gradle.ktx
plugins {
    kotlin("multiplatform") // or kotlin("jvm") or any other kotlin plugin
    kotlin("plugin.serialization") version "1.3.70"
}

build.gradle.ktx
buildscript {
    repositories {
    // artifacts are published to JCenter
    jcenter()
}

dependencies {
    implementation(kotlin("stdlib", KotlinCompilerVersion.VERSION)) // or "stdlib-jdk8"
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.20.0") // JVM dependency
}

proguard

proguardを利用している場合はrules追加が必要です。

proguard-rules.pro
-keepattributes *Annotation*, InnerClasses
-dontnote kotlinx.serialization.SerializationKt
-keep,includedescriptorclasses class com.yourcompany.yourpackage.**$$serializer { *; } # <-- change package name to your app's
-keepclassmembers class com.yourcompany.yourpackage.** { # <-- change package name to your app's
    *** Companion;
}
-keepclasseswithmembers class com.yourcompany.yourpackage.** { # <-- change package name to your app's
    kotlinx.serialization.KSerializer serializer(...);
}

これで導入は終わりです。

使用例

APIからのレスポンスがjsonできた場合のparseを例にご紹介します。

data class

まずは、Data classを作成します。

Data.kt

import kotlinx.serialization.*
import kotlinx.serialization.json.*

@Serializable // 1
data class Data(
  val id: Int,
  @SerialName("user_name") // 2
  val name: String = "hoge",
  @SerialName("mail_address")
  val mailAddress: String? = "" // 3
)
  1. @Serializable AnnotationをつけてSerializeの対象にします。
  2. @SerialName Annotationをつけると、parseした際のkey名を指定することができるので変数名を変えることができます。
  3. parseした際にそのdataがない可能性がある場合はあらかじめnullableにしておきます。(対応方法は後述)

その他にも@Requiredなど様々なAnnotationがあるので気になる方はコチラをご覧ください。

parse

上記のDataクラスを基にparseを処理を書きます。

// sample data
val json = """{"id":0,"user_name":"hoge","mail_address":"aaa@gmail.com"}"""

val obj = Json(JsonConfiguration.Stable).parse(Data.serializer(), json) // 1
  1. Json(JsonConfiguration.Stableはjsonをparseする上での設定になります。 JsonConfiguration.Stableはデフォルト設定なので省略も可能です。

その他のJsonConfiguration

しかし、jsonデータの中にあるmail_addressが返ってこないときに上記のparseをしてしまうと、parse errorが起きてしまいます。
そこで、nullableなvalueがある時にはその設定をしないといけません。

// sample data
val json = """{"id":0,"user_name":"hoge"}"""

val parsedJson = Json(
    JsonConfiguration(
       isLenient = true, // 1
       ignoreUnknownKeys = true,
       serializeSpecialFloatingPointValues = true
    )
).parse(Data.serializer(), json)

これで下記をnullableなvalueを扱っても問題なくparseをしてくれます。
1. それぞれのConfigの意味はコチラをご覧ください。

最後に

v0.14.0ではnullableなvalueがある場合は下記の指定をすればよかったので楽でした。

// sample data
val json = """{"id":0,"name":"hoge"}"""

val obj = Json.nonstrict.parse(Data.serializer(), json)

v0.2.0でも@UnstableDefaultがかなりの量があるので更新は随時追っていきましょう!

23
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
18