我从一个服务接收到一个相当深的JSON对象字符串,我必须解析为JSON对象,然后将其映射到类。

如何将JSON字符串转换为Kotlin对象?

在映射到各自的类之后,我使用了来自Jackson的StdDeserializer。当对象的属性也必须被反序列化为类时,问题就出现了。我无法在另一个反序列化器中获得对象映射器,至少我不知道如何获得。

最好是,在本地,我试图减少我需要的依赖项的数量,所以如果答案只是JSON操作和解析它就足够了。


当前回答

没有外部库(Android)

解析如下:

val jsonString = """
    {
       "type":"Foo",
       "data":[
          {
             "id":1,
             "title":"Hello"
          },
          {
             "id":2,
             "title":"World"
          }
       ]
    }        
"""

使用这些类:

import org.json.JSONObject

class Response(json: String) : JSONObject(json) {
    val type: String? = this.optString("type")
    val data = this.optJSONArray("data")
            ?.let { 0.until(it.length()).map { i -> it.optJSONObject(i) } } // returns an array of JSONObject
            ?.map { Foo(it.toString()) } // transforms each JSONObject of the array into Foo
}

class Foo(json: String) : JSONObject(json) {
    val id = this.optInt("id")
    val title: String? = this.optString("title")
}

用法:

val foos = Response(jsonString)

其他回答

我创建了一个简单的扩展函数来将JSON字符串转换为模型类

inline fun <reified T: Any> String.toKotlinObject(): T =
    Gson().fromJson(this, T::class.java)

使用方法

stringJson.toKotlinObject<MyModelClass>()

你可以使用Gson。

例子

步骤1

添加编译

compile 'com.google.code.gson:gson:2.8.2'

步骤2

将 json 转换为 Kotlin Bean(使用 JsonToKotlinClass)

像这样

Json数据

{
"timestamp": "2018-02-13 15:45:45",
"code": "OK",
"message": "user info",
"path": "/user/info",
"data": {
    "userId": 8,
    "avatar": "/uploads/image/20180115/1516009286213053126.jpeg",
    "nickname": "",
    "gender": 0,
    "birthday": 1525968000000,
    "age": 0,
    "province": "",
    "city": "",
    "district": "",
    "workStatus": "Student",
    "userType": 0
},
"errorDetail": null
}

科特林豆

class MineUserEntity {

    data class MineUserInfo(
        val timestamp: String,
        val code: String,
        val message: String,
        val path: String,
        val data: Data,
        val errorDetail: Any
    )

    data class Data(
        val userId: Int,
        val avatar: String,
        val nickname: String,
        val gender: Int,
        val birthday: Long,
        val age: Int,
        val province: String,
        val city: String,
        val district: String,
        val workStatus: String,
        val userType: Int
    )
}

步骤3

使用Gson

var gson = Gson()
var mMineUserEntity = gson?.fromJson(response, MineUserEntity.MineUserInfo::class.java)

从这里下载deme的源代码(Json解析在android kotlin)

添加这个依赖:

compile 'com.squareup.okhttp3:okhttp:3.8.1'

调用api函数:

 fun run(url: String) {
    dialog.show()
    val request = Request.Builder()
            .url(url)
            .build()

    client.newCall(request).enqueue(object : Callback {
        override fun onFailure(call: Call, e: IOException) {
            dialog.dismiss()

        }

        override fun onResponse(call: Call, response: Response) {
            var str_response = response.body()!!.string()
            val json_contact:JSONObject = JSONObject(str_response)

            var jsonarray_contacts:JSONArray= json_contact.getJSONArray("contacts")

            var i:Int = 0
            var size:Int = jsonarray_contacts.length()

            al_details= ArrayList();

            for (i in 0.. size-1) {
                var json_objectdetail:JSONObject=jsonarray_contacts.getJSONObject(i)


                var model:Model= Model();
                model.id=json_objectdetail.getString("id")
                model.name=json_objectdetail.getString("name")
                model.email=json_objectdetail.getString("email")
                model.address=json_objectdetail.getString("address")
                model.gender=json_objectdetail.getString("gender")

                al_details.add(model)


            }

            runOnUiThread {
                //stuff that updates ui
                val obj_adapter : CustomAdapter
                obj_adapter = CustomAdapter(applicationContext,al_details)
                lv_details.adapter=obj_adapter
            }

            dialog.dismiss()

        }

    })

这使用kotlinx。像以利沙的回答。与此同时,该项目已经过了1.0版本,因此API已经发生了变化。注意,例如JSON。parse被重命名为Json.decodeFromString。此外,从Kotlin 1.4.0开始,它以不同的方式导入gradle:

dependencies {
    implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.0"
}
apply plugin: 'kotlinx-serialization'

使用示例:

import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
@Serializable
data class Point(val x: Int, val y: Int)

val pt = Json.decodeFromString<Point>("""{"y": 1, "x": 2}""")
val str = Json.encodeToString(pt)  // type can be inferred!

val ilist = Json.decodeFromString<List<Int>>("[-1, -2]")
val ptlist = Json.decodeFromString<List<Point>>(
    """[{"x": 3, "y": 4}, {"x": 5, "y": 6}]"""
)

你可以对可空字段和可选字段使用可空类型(T?):

@Serializable
data class Point2(val x: Int, val y: Int? = null)

val nlist = Json.decodeFromString<List<Point2>>(
    """[{"x": 7}, {"x": 8, "y": null}, {"x": 9, "y": 0}]"""
)

Kotlin的数据类是一个主要保存数据的类,并具有自动定义的成员. tostring()和其他方法(例如解构声明)。

毫无疑问,Kotlin中解析的未来将是kotlinx.serialization。它是Kotlin库的一部分。kotlinx版本。序列化1.0终于发布了

https://github.com/Kotlin/kotlinx.serialization

import kotlinx.serialization.*
import kotlinx.serialization.json.JSON

@Serializable
data class MyModel(val a: Int, @Optional val b: String = "42")

fun main(args: Array<String>) {

    // serializing objects
    val jsonData = JSON.stringify(MyModel.serializer(), MyModel(42))
    println(jsonData) // {"a": 42, "b": "42"}
    
    // serializing lists
    val jsonList = JSON.stringify(MyModel.serializer().list, listOf(MyModel(42)))
    println(jsonList) // [{"a": 42, "b": "42"}]

    // parsing data back
    val obj = JSON.parse(MyModel.serializer(), """{"a":42}""")
    println(obj) // MyModel(a=42, b="42")
}