HOWTO · Kotlin

Kotlin で JSON の文字列をオブジェクトにパースする

このチュートリアルでは、JSON オブジェクトを Kotlin のオブジェクトに解析するために使用できるさまざまな方法を読者に教えます。

JSON は JavaScript Object Notation の略で、クライアントサーバーアーキテクチャがコンピューター間でデータを転送したりデータベースにデータを保存したりするために使用するデータ交換形式です。

JSON データは、データベースに格納されているデータに対して CRUD 操作を実行するためにサーバーに HTTP リクエストを発行する RESTAPI を使用して消費されます。たとえば、ウェブページやモバイルアプリケーションにデータを動的に読み込む場合、通常、このデータをデータベースから JSON として取得し、データをオブジェクトに解析して、各オブジェクト変数をビューに表示します。

このチュートリアルでは、JSON データを Kotlin のオブジェクトに解析するために使用できるさまざまな方法を学習します。

新規プロジェクトの作成と依存関係の追加

新しいプロジェクトを作成するには、Intellij に移動し、[ファイル]>[新規]>[プロジェクト]を選択します。開いたウィンドウで、プロジェクト名として kotlinSerialization と入力し、言語セクションで Kotlin を選択し、ビルドシステムセクションで Gradle を選択します。

作成ボタンを押して、新しいプロジェクトを生成します。プロジェクトが生成されたら、build.gradle.kts ファイルに移動し、次の依存関係があることを確認します。

dependencies {
    implementation ("com.fasterxml.jackson.module:jackson-module-kotlin:2.13.3")
    implementation ("com.google.code.gson:gson:2.9.0")
    implementation("org.json:json:20220320")
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.3")
    testImplementation(kotlin("test"))
}

各依存関係は、各実装の作成に使用する API を提供するため、未解決の参照エラーを回避するために、すべての依存関係があることを確認してください。

kotlinx.serialization ライブラリを使用して、JSON 文字列を Kotlin のオブジェクトに解析する

この例では、build.gradle.kts ファイルのプラグインセクションに次のプラグインがあることを確認する必要があります。

plugins {
    kotlin("jvm") version "1.7.0"
    kotlin("plugin.serialization") version "1.7.0"
}

Kotlin ファイルが作成されるプロジェクトの kotlin フォルダーの下にフォルダー構造 com/serialize を作成します。

serialize フォルダの下に UsingKotlinx.kt という名前のファイルを作成し、次のコードをコピーしてファイルに貼り付けます。

package com.serialize

import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json

val employeeJSON = """
    {
       "firstName": "john",
       "lastName": "doe",
       "email": "john@gmail.com"
    }
""".trimIndent()

@Serializable
data class Employee(val firstName: String,
                    val lastName: String,
                    val email: String)

fun main(args: Array<String>){
    //Decode employee from string
    val employeeObject = Json.decodeFromString<Employee>(employeeJSON);
    println(employeeObject);
}

上記のコードでは、Kotlin のトリプルクォートされたテキストを使用して JSON オブジェクトの複数行のテキストを作成し、従業員オブジェクトを表しています。trimIndent() メソッドは、すべての入力行の共通インデントを削除し、空白の場合は最初と最後の行を削除します。

次に、Employee クラスを作成し、@Serializable アノテーションを付けました。Employee クラスは、パラメータ firstNamelastName、および email を持つデータクラスです。

これらのパラメータはデータを保存するため、data キーワードになります。データクラスを使用すると、toString() などのメソッドを宣言せずにすぐに使用できます。これは、データをコンソールに記録する場合に重要です。

@Serializable アノテーションにより、Employee クラスがシリアル化可能になります。つまり、データベースやファイルに保存したり、ネットワーク経由で転送したりできる形式に変更できます。

JSON オブジェクトを Kotlin オブジェクトに解析するには、Json から decodeFromString() ジェネリックメソッドを呼び出します。従業員オブジェクトを返したいので、Employee クラスを type パラメーターに渡し、JSON 文字列をメソッドの引数として渡します。

print ステートメントは、解析されたオブジェクトをコンソールに記録します。コードを実行し、以下に示すように、オブジェクトが文字列としてコンソールに記録されることに注意してください。

Employee(firstName=john, lastName=doe, email=john@gmail.com)

org.json ライブラリを使用して、JSON 文字列を Kotlin のオブジェクトに解析する

この例では、org.json ライブラリによって提供される JSONObject API を利用します。このライブラリは、依存関係を追加するときにアプリケーションに含まれていることに注意してください。

serialize フォルダの下に UsingJSONObject.kt という名前のファイルを作成し、次のコードをコピーしてファイルに貼り付けます。

package com.serialize

import org.json.JSONObject

val usersArray = """
    {
       "User":[
          {
            "firstName": "john",
            "lastName": "doe",
            "email": "john@gmail.com"
          },
          {
            "firstName": "mary",
            "lastName": "public",
            "email": "mary@gmail.com"
          }

       ]
    }
""".trimIndent()

class User{
    var firstName: String? = null;
    var lastName: String? = null;
    var email: String? = null

    override fun toString(): String {
        return "User(firstName=$firstName, lastName=$lastName, email=$email)"
    }

}

fun main() {
    val userJsonObject =
        JSONObject(usersArray)

    val userObject = userJsonObject
        .getJSONArray("User");

    for (i in 0 until(userObject!!.length())){
        val theUser = User();

        val firstName = userObject
            .getJSONObject(i)
            .getString("firstName");
        theUser.firstName = firstName

        val lastName = userObject
            .getJSONObject(i)
            .getString("lastName")
        theUser.lastName = lastName

        val email = userObject
            .getJSONObject(i)
            .getString("email")

        theUser.email = email;

        println(theUser);
    }

}

最初と 2 番目の手順は、前の例で説明した手順と似ていますが、このクラスは JSON オブジェクトの配列を作成し、通常の Kotlin クラスを使用します。この例ではデータクラスを使用していないため、フィールド firstNamelastName、および email を使用してカスタム toString() メソッドを作成する必要があります。

JSON 配列を取得するには、JSONObject() コンストラクターを呼び出し、コンストラクターの引数として JSON 文字列を渡します。コンストラクターは、{ で始まり } で終わる文字列から JSON オブジェクトを作成します。文字列にエラーがある場合は、JSONException をスローします。

JSON オブジェクトにアクセスすると、そのプロパティを引数として渡すことで、必要なプロパティを取得できます。ユーザーの配列を取得するには、返されたオブジェクトから getJSONArray() メソッドを呼び出し、メソッドの引数として User を渡します。

このメソッドは、オブジェクトからユーザーの JSONArray を返します。

JSONArray からの Kotlin オブジェクトの作成は、ループを使用して手動で行われます。getJSONObject() メソッドを使用して、オブジェクトのインデックスをメソッドの引数として渡すことにより、配列から各オブジェクトを取得します。

このオブジェクトから、各変数を取得し、反復ごとに作成された新しい Kotlin オブジェクトに割り当てます。アプリケーションを実行して、次の文字列オブジェクトが出力されることを確認します。

User(firstName=john, lastName=doe, email=john@gmail.com)
User(firstName=mary, lastName=public, email=mary@gmail.com)

Gson ライブラリを使用して JSON 文字列を Kotlin のオブジェクトに解析する

serialize フォルダーの下に UsingGson.kt ファイルを作成し、次のコードをコピーしてファイルに貼り付けます。

package com.serialize

import com.google.gson.Gson

val customerObject = """
    {
       "firstName": "john",
       "lastName": "doe",
       "email": "john@gmail.com"
    }
""".trimIndent()

class Customer{
    private val firstName: String? = null;
    private val lastName: String? = null;
    private val email: String? = null;

    override fun toString(): String {
        return "Customer(firstName=$firstName, lastName=$lastName, email=$email)"
    }

}

fun main() {
    val theGson = Gson();
    val customer = theGson
        .fromJson(customerObject, Customer::class.java);
    println(customer);
}

最初のステップでオブジェクトの JSON 表現が作成され、2 番目のステップで文字列から Kotlin オブジェクトを作成するために使用されるクラスが作成されることを理解していると思います。

main メソッドは、Gson() コンストラクターを呼び出して、デフォルト構成で Gson オブジェクトを作成します。

JSON 文字列を Kotlin オブジェクトにマッピングするには、Gson オブジェクトから fromJson() メソッドを呼び出し、JSON 文字列をメソッドの最初の引数として渡し、class をメソッドの 2 番目のパラメーターとして渡します。

fromJson() メソッドは汎用であり、メソッドの 2 番目の引数として渡されたオブジェクトのタイプを返すことに注意してください。このメソッドは、ファイルから JSON オブジェクトを読み取るなど、他の実装を提供するためにもオーバーロードされます。

プログラムを実行し、次の文字列オブジェクトをコンソールに記録することに注意してください。

Customer(firstName=john, lastName=doe, email=john@gmail.com)

Jackson ライブラリを使用して JSON 文字列を Kotlin のオブジェクトに解析する

serialize フォルダの下に UsingJackson.kt という名前のファイルを作成し、次のコードをコピーしてファイルに貼り付けます。

package com.serialize

import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper

val vehicleObject = """
    {
      "vehicleName": "Toyota",
      "vehicleColor": "white",
      "vehiclePrice": 10000
    }
""".trimIndent()

data class Vehicle(private val vehicleName: String,
                   private val vehicleColor: String,
                   private val vehiclePrice: Int)

fun main() {
    val jacksonMapper = jacksonObjectMapper();

    val vehicle = jacksonMapper
        .readValue(vehicleObject, Vehicle::class.java)

    println(vehicle);
}

このコードでは、JSON オブジェクトを表す文字列と、文字列を Kotlin オブジェクトにマップするために使用されるクラスを作成しました。クラスで作成されるプロパティは、JSON 文字列のキーと同じである必要があります。

Jackson ライブラリを使用するには、main メソッドで jacksonObjectMapper() を呼び出して ObjectMapper を作成します。次に、ObjectMapperreadValue() メソッドを呼び出し、最初の引数として JSON 文字列を渡し、2 番目の引数としてマッピングされている class を渡します。

readValue() メソッドは JSON 文字列を逆シリアル化し、メソッドの 2 番目の引数として渡されたオブジェクトのタイプを返します。

コードを実行して、次のオブジェクトを文字列としてコンソールに記録することを確認します。

Vehicle(vehicleName=Toyota, vehicleColor=white, vehiclePrice=10000)

まとめ

このチュートリアルでは、JSON オブジェクトを Kotlin オブジェクトに解析する方法を学びました。ここで取り上げたアプローチには、kotlix.serialization ライブラリ、org.json ライブラリ、Gson ライブラリ、および Jackson ライブラリの使用が含まれます。

同じ目的を実現するために使用できるライブラリはこれらだけではないことに注意してください。他のライブラリを使用してアプリケーションを実装してください。