在 Kotlin 中將 JSON 字串解析為物件

David Mbochi Njonge 2023年1月30日
  1. 建立一個新專案並新增依賴項
  2. 使用 kotlinx.serialization 庫將 JSON 字串解析為 Kotlin 中的物件
  3. 使用 org.json 庫在 Kotlin 中將 JSON 字串解析為物件
  4. 使用 Gson 庫在 Kotlin 中將 JSON 字串解析為物件
  5. 使用 Jackson 庫在 Kotlin 中將 JSON 字串解析為物件
  6. まとめ
在 Kotlin 中將 JSON 字串解析為物件

JSON 代表 JavaScript Object Notation,一種資料交換格式,客戶端-伺服器架構使用它在計算機之間傳輸資料或將資料儲存在資料庫中。

使用 REST API 使用 JSON 資料,這些 API 向伺服器發出 HTTP 請求,以對儲存在資料庫中的資料執行 CRUD 操作。例如,當我們在網頁或移動應用程式上動態載入資料時,我們通常會從資料庫中以 JSON 格式檢索這些資料,將資料解析為物件,並將每個物件變數顯示到檢視中。

在本教程中,我們將學習在 Kotlin 中將 JSON 資料解析為物件的不同方法。

建立一個新專案並新增依賴項

要建立一個新專案,請轉到 Intellij 並選擇 File > New > Project。在開啟的視窗中,輸入 kotlinSerialization 作為專案名稱,在 Language 部分選擇 Kotlin,在 Build System 部分選擇 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() 方法刪除所有輸入行的 common 縮排,如果第一行和最後一行為空白,則刪除它們。

然後我們建立了一個 Employee 類並使用 @Serializable 註釋對其進行註釋。Employee 類是具有引數 firstNamelastNameemail 的資料類。

這些引數將儲存我們的資料,因此是 data 關鍵字。當我們使用資料類時,我們會在沒有宣告的情況下獲得一些開箱即用的方法,例如 toString(),這在你要將資料記錄到控制檯時至關重要。

@Serializable 註釋使 Employee 類可序列化,這意味著我們可以將其更改為可以儲存在資料庫、檔案中或通過網路傳輸的格式。

為了將我們的 JSON 物件解析為 Kotlin 物件,我們從 Json 呼叫 decodeFromString() 泛型方法。由於我們想要返回一個員工物件,我們將 Employee 類傳遞給型別引數,並將我們的 JSON 字串作為方法的引數。

print 語句將解析的物件記錄到控制檯。執行程式碼並注意該物件作為字串記錄到控制檯,如下所示。

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

使用 org.json 庫在 Kotlin 中將 JSON 字串解析為物件

在本例中,我們將使用 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);
    }

}

第一步和第二步與我們在上一個示例中介紹的類似,但是這個類建立了一個 JSON 物件陣列並使用了一個普通的 Kotlin 類。由於我們在這個例子中沒有使用資料類,我們必須使用欄位 firstNamelastNameemail 建立我們的自定義 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 庫在 Kotlin 中將 JSON 字串解析為物件

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 表示,第二步建立一個類,該類將用於從字串建立 Kotlin 物件。

main 方法呼叫 Gson() 建構函式以建立具有預設配置的 Gson 物件。

要將我們的 JSON 字串對映到 Kotlin 物件,請從 Gson 物件呼叫 fromJson() 方法並將 JSON 字串作為方法的第一個引數傳遞,並將 class 作為方法的第二個引數傳遞。

請注意,fromJson() 方法是通用的,它返回作為方法的第二個引數傳遞的物件型別。該方法還被過載以提供其他實現,例如從檔案中讀取 JSON 物件。

執行程式並注意它將以下字串物件記錄到控制檯。

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

使用 Jackson 庫在 Kotlin 中將 JSON 字串解析為物件

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 字串作為第一個引數傳遞,將對映的 class 作為第二個引數傳遞。

readValue() 方法反序列化 JSON 字串並返回作為方法的第二個引數傳遞的物件型別。

執行程式碼以驗證它將以下物件作為字串記錄到控制檯。

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

まとめ

在本教程中,我們學習瞭如何將 JSON 物件解析為 Kotlin 物件。我們介紹的方法包括:使用 kotlix.serialization 庫、org.json 庫、Gson 庫和 Jackson 庫。

請注意,這些不是我們可以用來實現相同目標的唯一庫,因此請隨意使用其他庫來實現你的應用程式。

David Mbochi Njonge avatar David Mbochi Njonge avatar

David is a back end developer with a major in computer science. He loves to solve problems using technology, learning new things, and making new friends. David is currently a technical writer who enjoys making hard concepts easier for other developers to understand and his work has been published on multiple sites.

LinkedIn GitHub