Gson - 如何在 Kotlin 中解析部分 json

Posted

技术标签:

【中文标题】Gson - 如何在 Kotlin 中解析部分 json【英文标题】:Gson - How to parse partial json in Kotlin 【发布时间】:2019-11-08 08:08:26 【问题描述】:

我有一个data class,叫做Model

data class Model(var name: String? = null, var address: String? = null) 

    override fun toString(): String 
        return "name: $name address: $address"
    

我有两个 json 字符串,

val json1 = " \"name\": \"Alex\", \"address\": \"rome, 1000\" "
val json2 = " \"name\": \"Alex\", \"address\": \"city\": \"rome\", \"post\": \"1000\"  "

下面的转换工作正常,

val model1 = Gson().fromJson<Model>(json1, Model::class.java)

但是,这个版本不工作。给出一个例外。

val model2 = Gson().fromJson<Model>(json2, Model::class.java)

例外:

E/androidRuntime: FATAL EXCEPTION: main
Process: com.achellies.kotlin, PID: 11211
java.lang.RuntimeException: Unable to start activity ComponentInfocom.achellies.kotlin/com.achellies.kotlin.MainActivity: com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Unterminated object at line 1 column 40 path $.address
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3086)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3229)
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1926)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:214)
    at

如何解析json2 以便address 字段将保存内部地址json 数据的字符串值?例如解析后address应该等于

"city": "rome", "post": "1000"

【问题讨论】:

【参考方案1】:

你试过Any吗?

data class Model(var name: String? = null, var address: Any? = null) 

    override fun toString(): String 
        return "name: $name address: $address"
    

试试这个,它会工作的。

祝你有美好的一天。 :)

【讨论】:

【参考方案2】:

您可以使用专门用于您的 Model 类的 JsonDeserializer,如下所示:

fun main() 
    val json1 = " \"name\": \"Alex\", \"address\": \"rome, 1000\" "
    val json2 = " \"name\": \"Alex\", \"address\": \"city\": \"rome\", \"post\": \"1000\"  "

    val gson = GsonBuilder().registerTypeAdapter(Model::class.java, ModelDeserializer()).create()

    println(gson.fromJson(json1, Model::class.java))
    println(gson.fromJson(json2, Model::class.java))


data class Model(val name: String, val address: String)

class ModelDeserializer : JsonDeserializer<Model> 

    override fun deserialize(json: JsonElement, typeOfT: Type, context:     JsonDeserializationContext): Model 
        json as JsonObject

        val name = json.get("name").asString

        val addressJson = json.get("address")
        val address = if (addressJson.isJsonObject) addressJson.asJsonObject.toString() else addressJson.asString

        return Model(name, address)
    

哪些输出:

Model(name=Alex, address=rome, 1000)
Model(name=Alex, address="city":"rome","post":"1000")

如果你使用 Kotson 库,看起来你就是这样,事情会变得更好:

val gson = GsonBuilder()
        .registerTypeAdapter<Model> 
            deserialize 
                val json = it.json.asJsonObject

                val name = json["name"].asString

                val addressJson = json["address"]
                val address = if (addressJson.isJsonObject) addressJson.asJsonObject.toString() else addressJson.asString

                Model(name, address)
            
        
        .create()

println(gson.fromJson<Model>(json1))
println(gson.fromJson<Model>(json2))

【讨论】:

非常感谢。它有帮助。【参考方案3】:

请尝试Any,它应该可以工作。

var address: String? = null

【讨论】:

【参考方案4】:

如果地址本身是一个有效的 json,那么你可以这样做:

val jsonObject = JSONObject(jsonString)
val address = jsonObject.optJSONObject("address").toString()

如果是字符串则

val address = jsonObject.optString("address").toString()

【讨论】:

但我需要将其解析为模型对象。我该怎么做? 您需要在这两种情况下都适用的解决方案吗?一种情况是只有城市名称在 json 中,而另一种情况是它可以是整个城市对象?或者你只是想让它适用于 json2? 我想使用 Gson 库解析 json2,以便将地址对象作为字符串分配给模型的地址字段。

以上是关于Gson - 如何在 Kotlin 中解析部分 json的主要内容,如果未能解决你的问题,请参考以下文章

如何在 kotlin 中通过 GSON lib 解析 JSON 时管理 android 应用程序的空值

Android kotlin解析器Gson Volley

如何在 Android 的 Kotlin 中使用 GSON 将 JSON 对象转换为 JSON 数组

如何使用带有 Kotlin 的 Gson 库访问 JSON 有效负载中的嵌套值

Gson 无法解析 Kotlin 中的字符串 json 格式数据

Kotlin基础从入门到进阶系列讲解(入门篇)Android之GSON的使用