Android:使用Moshi适配器解析内部非结构化Json
我很难解析JSON的某些内部部分(使用Moshi),这些内部部分可能变化很大,并且是高度非结构化的。总的看来:Android:使用Moshi适配器解析内部非结构化Json,android,json,gson,retrofit,moshi,Android,Json,Gson,Retrofit,Moshi,我很难解析JSON的某些内部部分(使用Moshi),这些内部部分可能变化很大,并且是高度非结构化的。总的看来: response: { items: [{ type: "typeA", data: { "1563050214700-001": { foo: 123 .... } } }, { type: "typeB",
response: {
items: [{
type: "typeA",
data: {
"1563050214700-001": {
foo: 123 ....
}
}
}, {
type: "typeB",
data: {
"1563050214700-002": {[
// differs a lot from previous one
{bar: 123 .... }
]}
}
}]
}
data class Response(
val items: Map<String,List<Item?>>?
) {
data class Item(
val type: String?,
val data: Map<String,List<DataItem?>>?
) {
data class DataItem(
// members highly unstructured
)
}
}
数据类结构如下所示:
response: {
items: [{
type: "typeA",
data: {
"1563050214700-001": {
foo: 123 ....
}
}
}, {
type: "typeB",
data: {
"1563050214700-002": {[
// differs a lot from previous one
{bar: 123 .... }
]}
}
}]
}
data class Response(
val items: Map<String,List<Item?>>?
) {
data class Item(
val type: String?,
val data: Map<String,List<DataItem?>>?
) {
data class DataItem(
// members highly unstructured
)
}
}
我如何做到这一点?任何示例或参考实现都会有所帮助。欢迎使用多态JSON解析问题word 我们正在编写自己的JSON适配器,如下所示:
internal class CardJsonAdapter(
moshi: Moshi
) : JsonAdapter<Card>() {
private val cardTypeAdapter = moshi.adapter(Card.Type::class.java)
private val amountsWithActionAdapter = moshi.adapter(AmountsWithActionCard::class.java)
private val backgroundImageCardAdapter = moshi.adapter(BackgroundImageCard::class.java)
@Suppress("TooGenericExceptionCaught")
override fun fromJson(reader: JsonReader): Card = try {
@Suppress("UNCHECKED_CAST")
val jsonMap = reader.readJsonValue() as Map<String, Any?>
val type = cardTypeAdapter.fromJsonValue(jsonMap["type"])
createCardWithType(type, jsonMap)
} catch (error: Exception) {
if (BuildConfig.DEBUG) {
Log.w("CardJsonAdapter", "Failed to parse card", error)
}
// Try not to break the app if we get unexpected data: ignore errors and return a placeholder card instead.
UnknownCard
}
override fun toJson(writer: JsonWriter, value: Card?) {
throw NotImplementedError("This adapter cannot write cards to JSON")
}
private fun createCardWithType(type: Type?, jsonMap: Map<String, Any?>) = when (type) {
null -> UnknownCard
Type.AMOUNTS_WITH_ACTION -> amountsWithActionAdapter.fromJsonValue(jsonMap)!!
Type.BACKGROUND_IMAGE_WITH_TITLE_AND_MESSAGE -> backgroundImageCardAdapter.fromJsonValue(jsonMap)!!
}
}
内部类CardJsonAdapter(
摩希:摩希
):JsonAdapter(){
private val cardTypeAdapter=moshi.adapter(Card.Type::class.java)
private val amountsWithActionAdapter=moshi.adapter(AmountsWithActionCard::class.java)
private val backgroundImageCardAdapter=moshi.adapter(BackgroundImageCard::class.java)
@抑制(“TooGenericeExceptionCapture”)
override fun fromJson(reader:JsonReader):Card=try{
@抑制(“未选中的_CAST”)
val jsonMap=reader.readJsonValue()作为映射
val type=cardTypeAdapter.fromJsonValue(jsonMap[“type”])
createCardWithType(类型,jsonMap)
}捕获(错误:异常){
if(BuildConfig.DEBUG){
Log.w(“CardJsonAdapter”,“解析卡失败”,错误)
}
//如果收到意外数据,请尝试不要中断应用程序:忽略错误并返回占位符卡。
未知卡片
}
重写fun-toJson(writer:JsonWriter,value:Card?){
抛出NotImplementedError(“此适配器无法将卡写入JSON”)
}
private fun createCardWithType(类型:type?,jsonMap:Map)=何时(类型){
空->未知卡片
键入.AMOUNTS\u并单击\u ACTION->amountsWithActionAdapter.fromJsonValue(jsonMap)!!
键入.BACKGROUND\u IMAGE\u,带有标题和消息->backgroundImageCardAdapter.fromJsonValue(jsonMap)!!
}
}
然而,它不再是必需的。Moshi现在支持多态JSON解析-制作自定义适配器
class YourAdapter {
@FromJson
fun fromJson(reader: JsonReader, itemsAdapter: JsonAdapter<ItemsResponse>): List<ItemsResponse>? {
val list = ArrayList<ItemsResponse>()
if (reader.hasNext()) {
val token = reader.peek()
if (token == JsonReader.Token.BEGIN_ARRAY) {
reader.beginArray()
while (reader.hasNext()) {
val itemResponse = itemsAdapter.fromJsonValue(reader.readJsonValue())
itemsResponse?.let {
list.add(itemResponse)
}
}
reader.endArray()
}
}
return list
}
}
class适配器{
@FromJson
来自JSON的乐趣(reader:JsonReader,itemsAdapter:JsonAdapter):列表{
val list=ArrayList()
if(reader.hasNext()){
val-token=reader.peek()
if(token==JsonReader.token.BEGIN\u数组){
reader.beginArray()
while(reader.hasNext()){
val itemResponse=itemsAdapter.fromJsonValue(reader.readJsonValue())
项目响应?让我们{
list.add(itemResponse)
}
}
reader.endArray()
}
}
返回列表
}
}
谢谢。然而,在本文中的示例中,不同类型的有效负载有一个区分“动作”:“谈话”、“动作”:“流”等的字段。当没有这些区别并且完全匹配不同的有效负载模式时,这种方法能起作用吗?我不这么认为。您必须实现对所有可能的解析解决方案的迭代,并自己选择正确的解决方案。你对BE有影响吗?你能让他们给JSON增加一些区别吗?不幸的是,我不能改变。在任何情况下,您的响应都是有用的(在多态解析上),因此将标记为已接受。谢谢