はじめに
TechBoosterの書籍でKotlin Serializationが少し触れられていたのですが、現在開発中のプロジェクトで利用できそうだったため、もう少し詳しく調べてみることにしました。
Kotlin Serializationとは
- シリアライザ・デシリアライザである(コード自動生成用のコンパイラプラグインとシリアライズ用のランタイムライブラリの構成)
- JSON, CBOR, Protobufの3つのフォーマットをサポートし、さらに有志が作成したアドオンを使えばHOCON, YAMLも使える
- Kotlin/JVM, Kotlin/JS, Kotlin/Nativeプラットフォームをサポート
- リフレクションを使用しない ー> リフレクション使用しない分速い!
(MoshiやGsonなどのパーサーはJsonキーとプロパティを紐付ける際などにリフレクションを使用している)
インストール手順
- 今回はAndroidを前提にしているのでその他のプラットフォーム用の設定は公式参照のこと
build.gradle
buildscript {
ext.kotlin_version = '1.3.20'
repositories { jcenter() }
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
}
}
app/build.gradle
apply plugin: 'kotlin'
apply plugin: 'kotlinx-serialization'
// 略
repositories {
jcenter()
// artifacts are published to this repository
maven { url "https://kotlin.bintray.com/kotlinx" }
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.10.0"
}
使い方
import kotlinx.serialization.*
import kotlinx.serialization.json.Json
@Serializable
data class Data(val a: Int, @Optional val b: String = "42")
fun main(args: Array<String>) {
// Serializableアノテーションを付けた場合、オブジェクトを渡すだけでOK
val jsonData = Json.stringify(Data(42))
// コレクション等も拡張関数serializerを使うことで利用可能
val jsonList = Json.stringify(Data.serializer().list, listOf(Data(42)))
println(jsonData) // {"a": 42, "b": "42"}
println(jsonList) // [{"a": 42, "b": "42"}]
// 文字列をパースするときも簡単!
val obj = Json.parse<Data>("""{"a":42}""")
println(obj) // Data(a=42, b="42")
// unquotedはフォーマットからダブルクォーテーションを外す
assertEquals("{a:1, b:42}", Json.unquoted.stringify(Data(1)))
assertEquals(Data(1), Json.unquoted.parse<Data>("{a:1, b:42}"))
}
引用元: https://github.com/Kotlin/kotlinx.serialization#quick-example
アノテーションについて
アノテーション | 概要 |
---|---|
Serializable | シリアライズしたいカスタムクラスに付けることでシリアライゼーションできる |
Optional | 必須ではないパラメータに付ける。付けない場合はエラーになる |
SerialName | Jsonキー名が異なる場合に付ける |
Transient | Jsonで扱わないプロパティを定義したい場合に使用する。Jsonにこのプロパティが存在していた場合エラーになる |
SerialInfo | アノテーションクラスを定義するためのアノテーション。 プロパティにタグなどの情報をもたせることが出来て、エンコーダー内でタグをもとに条件分岐などに利用できる。 Protobufなどで利用する |
アノテーションの使い方
// シリアライズしたいクラスに付与
@Serializable
data class Data(
val a: Int,
// 必須パラメーターではない場合に付ける
@Optional
val b: String = “42”,
// jsonキー名がcでプロパティ名とことなる場合
@SerialName("c")
val d: String
)
カスタムシリアライザ
- シリアライザを自作することも可能。このサンプルは日付を扱う例
@Serializer(forClass = Date::class)
object DateSerializer: KSerializer<Date> {
private val df: DateFormat = SimpleDateFormat("dd/MM/yyyy HH:mm:ss.SSS")
override val descriptor: SerialDescriptor =
StringDescriptor.withName("WithCustomDefault")
override fun serialize(output: Encoder, obj: Date) {
output.encode(df.format(obj))
}
override fun deserialize(input: Decoder): Date {
return df.parse(input.decode())
}
}
終わりに
いかがでしたでしょうか?皆さんもKotlin Serializationを使って快適なシリアライゼーション生活を。