1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【2020年秋版】kotlinx.serializationで配列のJson文字列をパース

Last updated at Posted at 2020-09-25

バージョン

kotlin: 1.4.10
kotlinx:kotlinx-serialization-runtime: 1.0-M1-1.4.0-rc

ちょっと前まで使えてたのにストライクスルー

 さてこの周辺は目まぐるしく更新されていて、あら新しいバージョンあるじゃないとばかりにGradleを触っちゃうとすぐにIntelliJに怒られる昨今、皆様いかがお過ごしかってコロナで大変なんだよな。みんなそう俺もそう。誰だってそう。

 そんな自分らしさの檻の中でもがいてるあなたと私のために、今現在の情報を残しておこう、と。いつまで使えるのかわかんないけどね。

取り敢えずbuild.gradle

build.gradle
buildscript {
    ext.kotlin_version = '1.4.10'
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
    }
}

plugins {
    id 'org.jetbrains.kotlin.jvm' version "$kotlin_version"
    id "org.jetbrains.kotlin.plugin.serialization" version "$kotlin_version"
}

 こうやってkotlinのバージョンを1.4.10にすると、kotlinx-serialization-runtimeもバージョンをあげないといけなくて、rcとか付いてるけど今んとこはこれしかないのかな。

build.gradle
dependencies {
    implementation 'org.jetbrains.kotlinx:kotlinx-serialization-runtime:1.0-M1-1.4.0-rc'
}

 kotlinを書くようになってもbuild.gradle.ktsは馴染まないんだよな。ここだけはGroovyなのよね。kotlin-stdlibとかkotlin-reflectとかは省略してます。

使い方

 まずデータクラス。なんかオーバーライドしたらどう? って言ってくるけど、へいへい言うなりになるのもよし、無視するのもよし。よしなに。

sample1.kt
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class Container(
    @SerialName("Id")
    val id: String,
    @SerialName("Names")
    val names: Array<String>,
    @SerialName("State")
    val state: String,
    @SerialName("Mounts")
    val mounts: Array<Mounts>,
)

@Serializable
data class Mounts(
    @SerialName("Source")
    val source: String,
    @SerialName("Destination")
    val destination: String,
)

 ほんでメインクラス。Container.serializer().listが使えなくなってる。
 サンプルはDockerにコンテナの情報よこせとやっている。一文字の適当な変数名とか誰かに怒られるかも知れないが、怒られたら謝ればいい。人生はそんなもんだ。

sample2.kt
fun main(args: Array<String>) {
    val o = RestTemplate().getForObject("http://localhost:2375/containers/json?all=true") as String

    Json { isLenient = true; ignoreUnknownKeys = true }
        .decodeFromString(ListSerializer(Container.serializer()), o)
        .forEach { println(it) }
}

 RestTemplateだからあれだ、org.springframework:spring-web:5.2.9.RELEASEこれか、うん。spring-data-rest-coreも必要だったかな。ま、いいや。HTTPで取るだけならもっとオサレな方法があるのかね。fuelとか?

 ま、本筋じゃないからそこはいいや。

 試しにfuel使ってみたらめっちゃ素敵やん。自分でExtension functions書く必要なかった。最高かよ。ありがとう、世界のみんな。

build.gradle
implementation 'com.github.kittinunf.fuel:fuel:2.3.0'
sample3.kt
fun main(args: Array<String>) {
    val (_, _, result) = "http://localhost:2375/containers/json?all=true".httpGet().responseString()

    result.success {
        Json { isLenient = true; ignoreUnknownKeys = true }
            .decodeFromString(ListSerializer(Container.serializer()), it)
            .forEach { println(it) }
    }
}

 「fuel使うならfuel-jsonで良くね?」とか思ったかも知れないが、**その通りである。**でも記事の趣旨的に仕方ないんだ。本当は知らなかったんだけどプライドが許さないからそれは内緒なんだ。知ってたけど敢えてと言い張る方針でいきます。

以上でござる

 Json.nonstrictJson.parseも打ち消し線バーンだもんな。
 ちょっと前まで使ってた奴に打ち消し線が出ると、アクティブに更新されてる感じがするわけで、そういうのを見ると嬉しくなっちゃうタイプなら、僕だってそう誰だってそうなんだ。

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?