【问题标题】:Parse NoSQL Response with Gson使用 Gson 解析 NoSQL 响应
【发布时间】:2019-09-24 15:58:35
【问题描述】:

我正在尝试解析从 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,会发生变化,因此鉴于这些键的未知性质,很难获得数据模型类。

【问题讨论】:

    标签: android json nosql gson


    【解决方案1】:

    您需要实现自己的自定义序列化器/反序列化器,以使用动态键值解析 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 架构发生变化时进行未来的验证,以便您尽早发现它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多