gpt4 book ai didi

json - 如何使用动态对象反序列化JSON?

转载 作者:行者123 更新时间:2023-12-02 13:12:46 26 4
gpt4 key购买 nike

我有一个简单的json,但包含字段具有动态对象。例如,json看起来像

{
"fixedField1": "value1",
"dynamicField1": {
"f1": "abc",
"f2": 123
}
}

要么
{
"fixedField1": "value2",
"dynamicField1": {
"g1": "abc",
"g2": { "h1": "valueh1"}
}
}

我正在尝试序列化此对象,但不确定如何映射动态字段
@Serializable
data class Response(
@SerialName("fixedField1")
val fixedField: String,

@SerialName("dynamicField1")
val dynamicField: Map<String, Any> // ???? what should be the type?
)

上面的代码失败,并出现以下错误

Backend Internal error: Exception during code generation Cause: Back-end (JVM) Internal error: Serializer for element of type Any has not been found.

最佳答案

当我不得不序列化任意Map<String, Any?>时遇到了类似的问题

到目前为止,我设法做到这一点的唯一方法是使用JsonObject / JsonElement API并将其与@ImplicitReflectionSerializer组合

主要的缺点是使用了反射,该反射仅在JVM中正常工作,对于kotlin-multiplatform来说不是一个好的解决方案。

    @ImplicitReflectionSerializer
fun Map<*, *>.toJsonObject(): JsonObject = JsonObject(map {
it.key.toString() to it.value.toJsonElement()
}.toMap())

@ImplicitReflectionSerializer
fun Any?.toJsonElement(): JsonElement = when (this) {
null -> JsonNull
is Number -> JsonPrimitive(this)
is String -> JsonPrimitive(this)
is Boolean -> JsonPrimitive(this)
is Map<*, *> -> this.toJsonObject()
is Iterable<*> -> JsonArray(this.map { it.toJsonElement() })
is Array<*> -> JsonArray(this.map { it.toJsonElement() })
else -> {
//supporting classes that declare serializers
val jsonParser = Json(JsonConfiguration.Stable)
val serializer = jsonParser.context.getContextualOrDefault(this)
jsonParser.toJson(serializer, this)
}
}


然后,要序列化,请使用:

val response = mapOf(
"fixedField1" to "value1",
"dynamicField1" to mapOf (
"f1" to "abc",
"f2" to 123
)
)


val serialized = Json.stringify(JsonObjectSerializer, response.toJsonObject())

注意

仅当您必须使用 Map<String, Any?>时,才需要基于此反射的序列化

如果您可以自由使用自己的DSL来构建响应,则可以直接使用 json DSL,这与 mapOf非常相似
val response1 = json {
"fixedField1" to "value1",
"dynamicField1" to json (
"f1" to "abc",
"f2" to 123
)
}

val serialized1 = Json.stringify(JsonObjectSerializer, response1)

val response 2 = json {
"fixedField1" to "value2",
"dynamicField1" to json {
"g1" to "abc",
"g2" to json { "h1" to "valueh1"}
}
}

val serialized2 = Json.stringify(JsonObjectSerializer, response2)

但是,如果您必须定义数据类型,并进行序列化和反序列化,则可能无法使用 json DSL,因此必须使用上述方法定义 @Serializer

在Apache 2许可下,此类序列化程序的示例位于: ArbitraryMapSerializer.kt

然后,可以在具有任意 Map的类上使用它。在您的示例中,它将是:
@Serializable
data class Response(
@SerialName("fixedField1")
val fixedField: String,

@SerialName("dynamicField1")
@Serializable(with = ArbitraryMapSerializer::class)
val dynamicField: Map<String, Any>
)

关于json - 如何使用动态对象反序列化JSON?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57178093/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com