在 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