在我的应用程序中,我使用套接字。从套接字传入的消息是json,我想将每个jsonMap到每个相应的对象。
例如,我有json。
{ "er": { "i":"1001", "m":"message text" } }
与数据类匹配
data class Error(
val er: Er
)
data class Er(
val i: String,
val m: String
)
但我也有一个json像
{
"statusCode":200, "body":{
"au":{
"a": 44,
}
}
}
即数据类
data class Authentication(
val body: Body,
val statusCode: Int
)
data class Body(
val au: Au
)
data class Au(
val a: Int
)
默认情况下,我知道我的API永远不会有相同类型的json!
所以我试着做些像
try {
val thing = Gson().fromJson(mJson, Error::class.java)
// This json is Error type of object. Do something with it
catch(e: JsonSyntaxException) {
// This json is not Error object. Maybe its Authentication
// Proceed to check another object
}
然而,我注意到没有发生异常,并且thing
是一个具有空字段的Error
对象。
是否有任何机制或库可以在哪个对象中找到jsonMap?
1条答案
按热度按时间balp4ylt1#
你可以用kotlinx.serialization库来实现这一点。但是首先你需要把可能的反序列化类型的集合缩小到一个多态类层次结构。在大多数情况下,它可以是一个接口:
所有可能是反序列化结果的类型都应实现它;并且反序列化中涉及的所有类都应该使用
@Serializable
注解进行标记:但是反序列化库不是一个通灵的东西,JSON内容应该有一些独特的区别特征,这样反序列化库才能将其Map到特定的类型。
最简单的实现方法是将带有FQN目标类型值的
type
字段添加到每个JSON对象(如{"type": "Error", "er": { "i":"1001", "m":"message text" } })
)。之后,您需要注册该字段的所有可能值(一组确切的类型,实现该接口,这可能是反序列化结果):然后将它传递给
serializersModule
属性,神奇的事情发生了:如果不能修改JSON格式,那么需要创建自己的反序列化器,并根据JSON内容手动定义选择类型的算法(更准确地说是它的反序列化器),例如,在本例中,你可以说“如果JSON有
statusCode
字段,那么它必须是Authentication
,否则它是Error
“:然后将其作为序列化程序传递,瞧: