如何将 JSON 字符串解码为给定的 KClass?
Posted
技术标签:
【中文标题】如何将 JSON 字符串解码为给定的 KClass?【英文标题】:How to decode a JSON string to a given KClass? 【发布时间】:2022-01-06 21:03:41 【问题描述】:我的代码结构是这样的:
文件 1:
abstract class SomeClass
abstract fun print()
companion object
val versions = arrayOf(ClassV1::class, ClassV2::class)
@Serializable
data class ClassV1(val x: Int) : SomeClass()
override fun print()
println("Hello")
@Serializable
data class ClassV2(val y: String) : SomeClass()
override fun print()
println("World")
文件 2:
fun <T : SomeClass> getSomeObject(json: String, kClass: KClass<T>): SomeClass
return Json.decodeFromString(json)
fun printData(version: Int, json: String)
val someClass: SomeClass = getSomeObject(json, SomeClass.versions[version])
someClass.print()
我在printData
中有一个json
,它是SomeClass
的某个子类的序列化形式。我还有一个version
,用于确定json
代表的类结构。基于version
,我想将我的json字符串反序列化为SomeClass
的适当子类。
现在 getSomeObject
函数将 json 反序列化为 SomeClass
(如预期的那样崩溃)。我想知道是否有办法将其反序列化为提供的KClass
。
我知道我可以这样做:
val someClass = when (version)
0 -> Json.decodeFromString<ClassV1>(json)
else -> Json.decodeFromString<ClassV2>(json)
但我试图避免这种情况,因为我可以有很多这样的版本。有没有更好的办法?
【问题讨论】:
这有帮助吗? github.com/Kotlin/kotlinx.serialization/blob/master/docs/… @dnault 我浏览了那个文档。无法理解整个事情,但看起来它肯定比when
声明更有效。
@ArpitShukla 您正在尝试进行多态序列化。如果您想这样做,您将需要理解/阅读该文档。这基本上是你的答案。如果您不了解该文档的某些内容,可以将您的问题集中在 上。附:不,这并不比when
声明更多的工作。 kotlinx.serialization
的 SerializersModule
本质上等同于(逻辑上)when
语句。
【参考方案1】:
在我看来,您正在寻找以下内容:
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "version",
visible = false)
@JsonSubTypes(
JsonSubTypes.Type(value = ClassV1::class, name = "V1"),
JsonSubTypes.Type(value = ClassV2::class, name = "V2"))
abstract class SomeClass
(...)
这基本上意味着您的 JSON 将根据 JSON 属性 version
反序列化为 ClassV1
或 ClassV2
:
V1
表示ClassV1
是目标类;
V2
表示ClassV2
是目标类。
您可以在以下在线资源中找到更多相关信息:
https://fasterxml.github.io/jackson-annotations/javadoc/2.4/com/fasterxml/jackson/annotation/JsonTypeInfo.html https://fasterxml.github.io/jackson-annotations/javadoc/2.5/com/fasterxml/jackson/annotation/JsonSubTypes.Type.html https://www.baeldung.com/jackson-annotations#jackson-polymorphic-type-handling-annotations【讨论】:
感谢您的回答。我想知道是否可以使用 kotlinx.serialization 来做到这一点,因为我在一个项目中负担不起多个 json 解析库。但在这里我也必须为所有version
s 指定JsonSubTypes.Type
。我想我会采用我之前的 when
方法。
与kotlinx.serialization
我不知道有什么方法可以做到这一点,但也许是可能的。
这是给 Jackson 的。 OP正在询问kotlinx.serialization
。 -1以上是关于如何将 JSON 字符串解码为给定的 KClass?的主要内容,如果未能解决你的问题,请参考以下文章
如何修复“JSONDecodeError:无法解码 JSON 对象:第 1 行第 0 列(字符 0)”?