android - 改造 Moshi 如何将具有不同字段的对象数组转换为 POJO
问题描述
我很难考虑如何将以下 JSON 转换为 Moshi 数据类。我也无法更改 API 的工作方式,因为 API 不是我的。
JSON在下面:
{
"relationships": [
{
"id": "66a36824-04e6-452c-b9d2-679ac589cb8a",
"type": "artist",
"attributes": {
"name": "Nyunyu",
"imageUrl": null,
"biography": [],
"createdAt": "2021-04-19T21:59:45+00:00",
"updatedAt": "2021-04-19T21:59:45+00:00",
"version": 1
}
},
{
"id": "a050afdf-7377-4fe6-8317-fe7b38d1e000",
"type": "cover_art",
"attributes": {
"description": "",
"volume": null,
"fileName": "b0d63a0b-dd95-468c-b3e1-098e1414f6e9.jpg",
"createdAt": "2021-05-24T18:35:46+00:00",
"updatedAt": "2021-05-24T18:35:46+00:00",
"version": 1
}
}
]
}
我发现不可能转换,因为如果你有一个相同对象的数组,那么每个对象必须共享相同的结构对!但在这种情况下,我被迫这样做。请注意,它们具有完全不同的字段。
@JsonClass(generateAdapter = true)
data class Attributes (
@Json(name = "name") val name : String,
@Json(name = "imageUrl") val imageUrl : String,
@Json(name = "biography") val biography : List<String>,
@Json(name = "createdAt") val createdAt : String,
@Json(name = "updatedAt") val updatedAt : String,
@Json(name = "version") val version : Int
)
@JsonClass(generateAdapter = true)
data class Attributes (
@Json(name = "description") val description : String,
@Json(name = "volume") val volume : String,
@Json(name = "fileName") val fileName : String,
@Json(name = "createdAt") val createdAt : String,
@Json(name = "updatedAt") val updatedAt : String,
@Json(name = "version") val version : Int
)
当然,它不能编译,因为我们不能有两个同名的类。那么在这种情况下我该怎么办呢?
解决方案
您需要一个 Moshi 自定义转换器,可能需要创建 2 个类,ArtistAttributes
它们CoverArtAttributes
从基Attributes
类继承了它们的一些公共属性。然后在自定义转换器中检查 type json 属性,如果等于则covert_art
创建 CoverArtAttributes 对象,否则创建另一个。
然后在你的父类中,你应该有类似的东西:
data class Relationship constructor (
@Json(name = "id") val id : String,
@Json(name = "type") val type : String,
@Json(name = "attributes") val attributes : Attributes,
)
class AttributesAdapter {
@ToJson
fun toJson(Attributes attributes): String {
//ignore if you don't need opposite conversion
}
@FromJson
fun fromJson(String json): Attributes {
val moshi = Moshi.Builder().build()
val jsonObject = JSONObject(json)
val type = jsonObject.getString("type")
val adapter = when (type) {
"artist" -> {
moshi.adapter(ArtistAttributes::class.java)
}
"cover_art" -> {
moshi.adapter(CoverArtAttributes::class.java)
}
else -> throw IllegalArgumentException("unhandled type")
}
return adapter.fromJson(json)
}
}
然后你需要添加AttributesAdapter
到父 Moshi 实例并使用它来转换 JSON。
PS:以上代码未经测试,您可能需要进行调整才能使其正常工作,但它可以给您一些提示。
有关此主题的更多信息,请Moshi custom adapters
在 Internet 上搜索,周围有一些有用的资源
推荐阅读
- tensorflow - 使用 Triplet Loss 神经网络没有学到任何有意义的东西
- firebase - 如何在 Next.js SSR 应用程序中对 Firebase 中的数据进行分页?
- python - RDKit ERG 节点属性名称 python
- react-native - 反转选项卡导航器方向以支持 RTL 反应导航
- python - 无法写入csv文件
- jquery - Visual Studio插件中的jquery数据表不起作用
- reactjs - reactjs中如何通过点击header内容来控制body内容?
- javascript - 为什么在我的列表中创建了 5 个元素?需要创建计数功能。JavaScript
- python - 我无法安装 web3,因为 rlp 出错
- java - kotlin 中的 supportFragmentManager.commit 不起作用