使用 Gson & Retrofit 使用多态 json "data: put_anything_here "
Posted
技术标签:
【中文标题】使用 Gson & Retrofit 使用多态 json "data: put_anything_here "【英文标题】:Consuming polymorphic json "data: put_anything_here " with Gson & Retrofit使用 Gson & Retrofit 使用多态 json "data: put_anything_here " 【发布时间】:2021-12-30 18:09:07 【问题描述】:我不确定多态是否是正确的术语,所以我很抱歉。
我正在使用以下 API:
请求正文:
"user_id": "user_id",
"command": "submit_document",
回应:
"result": "success",
"code": 200,
"status": "ok",
"screen": "documents_rejected", // This is unique for different `data`
"next_screen": "",
"message": "Successful",
"data":
// `data` is always a json object with known fields and parameters
我已经为不同类型的data
响应准备了数据类,例如:
data class PhoneData(
@SerializedName("phone_number")
val phoneNumber: String? = null,
@SerializedName("phone_status")
val phoneStatus: String? = null
)
"screen": "phone"
和以下用于另一个屏幕:
data class Data(
val deepLink: String? = null
)
问题是,一开始,我必须发出以下请求来检索当前屏幕:
"user_id": "user_id",
"command": "get_current_screen",
返回与上述类似的响应:
"result": "success",
"code": 200,
"status": "ok",
"screen": "main_screen", // Different types of screen types are known.
"next_screen": "",
"message": "Successful",
"data":
// `data` is always a json object but the object could contain anything depending on the `screen` type.
但数据字段可能包含任何内容,具体取决于 screen
data class SplashScreenData(
// How do I make this data class combine all other data classes? One ugly approach is to add all the fields from different `data` classes here and use this one only.
)
我发现了用于多态情况的 RuntimeTypeAdapterFactory,但我不确定如何在 data
对象中没有类似“类型”的字段时使其工作(screen
是唯一的,但它在数据对象之外)。
如果有人有解决方案或可以为我指明方向,那将非常有帮助。
【问题讨论】:
调用获取数据的时候你知道数据是什么类型吗?如果是这样,您可以将数据的类型设置为模板参数并以这种方式对其进行解析(您必须告诉 GSON 模板是什么)。如果您不知道但有一组固定的可能性,您可以编写一个自定义反序列化器来查看数据并正确反序列化它,但数据可能需要键入 Any。 没有。打电话的时候不知道是什么类型。是的,有一组固定的可能性。会试试的,谢谢! 您可以使用screen
参数将data
对象反序列化或序列化到其各自的类中。
不知道为什么你之前没有尝试搜索并节省你和其他人的时间,但是 Gson 几乎内置了这个:***.com/questions/19588020/…
【参考方案1】:
val frameTextReceived: String = frame.readText()
val jsonObject = JsonParser.parseString(frameTextReceived).asJsonObject
val type = when (jsonObject.get("type").asString)
TYPE_JOIN_ROOM -> JoinRoom::class.java
TYPE_GAME_MOVE -> GameMove::class.java
TYPE_DISCONNECT_REQUEST -> DisconnectRequest::class.java
else -> BaseModel::class.java
val payload = gson.fromJson(frameTextReceived, type)
这是我的解决方案,这里我有 type
参数,通过它我可以知道我必须在哪个类中反序列化对象,但在你的情况下,你有 screen
参数,你可以使用它。
【讨论】:
以上是关于使用 Gson & Retrofit 使用多态 json "data: put_anything_here "的主要内容,如果未能解决你的问题,请参考以下文章
如何使用Retrofit2,RxJava2,Gson TypeAdapterFActory正确映射Gson?
当列表的各个项目使用Retrofit和Gson的格式不同时,如何解析json列表?