用Gson解析NoSQL响应

时间:2019-09-24 15:58:35

标签: android json nosql gson

我正在尝试解析从mongoDB实例返回的JSON对象,并且在解析文档ID时遇到问题。请参见下面的示例响应:

{  
    "type_id":"zyxwv54321",
    "content":{  
       "contentsA":{  
          "abcd123":{  },
          "efgh123":{  },
          "ijkl123":{  },
          "mnop123":{  },
          "qrst123":{  },
          "uvwx123":{  },
          "yzab123":{  }
       },
       "contentsB":{  
          "abcd123":{  },
          "efgh123":{  },
          "ijkl123":{  },
          "mnop123":{  },
          "qrst123":{  },
          "uvwx123":{  },
          "yzab123":{  }
       }
    },
    "manager":"mail@mail.com"
}

问题出在contentsAcontentsB中的对象,我该如何解析这些对象?这些对象中包含的每个字符串都是唯一的ID,该ID会发生变化,因此鉴于这些键的未知性质,很难获得数据模型类。

1 个答案:

答案 0 :(得分:0)

您将需要实现自己的自定义序列化器/反序列化器,以解析具有动态键值的JSON。它不会很漂亮,但是并不可怕。并且实际上在性能方面提供了几个优势:

  1. 您的JSON不会一次全部解析,而是以流方式解析
  2. 您可以用它做一些有趣的事情,因为您可以使用一些反应性编程和一些持久性存储来包装数据,并在解析JSON时立即开始向用户显示某些内容(因为用户讨厌等待...)

使用GSON(但是实际上任何库在概念上都是相似的),您需要在解析算法+ implement a custom TypeAdapter中描述您的对象,以便您的网络调用可以返回填充的数据模型类。像这样:

val jsonReader = JsonReader(inputStream.reader())
jsonReader.isLenient = true //I recommend reading up on this flag
jsonReader.beginObject()
parseInternals(jsonReader)
jsonReader.endObject()

现在,在您的parseInternal函数中,您需要在响应流传输时浏览各个字段,并检查JsonToken类型(它是一个枚举)

fun parseInternals(jsonReader: JsonReader): YourDataModel {
 //check there are still tokens to parse in your JSON
 val yourDataModel = YourDataModel()
 while (jsonReader.hasNext()) { 
   //name is a key in your JSON
   if (jsonReader.peek() == JsonToken.NAME) { 
     val fieldName = jsonReader.readName()
     if (fieldName == "type_id") {
       dataModel.typeId = jsonReader.nextString()

     }
     //and so on until you populate your data model class
   }
 }
}

您的下一个令牌将是 content ,它是从另一个对象开始的,因此您需要手动执行jsonReader.begin/endObject(),直到获得那些动态nextName在您的解析器中。确保使用jsonReader.peek()继续检查下一个令牌的类型,并将其与您期望的令牌进行比较。

在编写解析器之后,为其编写一些单元测试,以确保它正在执行您期望的功能。如果JSON模式发生更改,这将有助于将来的证明,以便您尽早发现它。

相关问题