使用未知密钥对JSON进行序列化

时间:2018-07-29 18:38:15

标签: json rest api dart flutter

我正在使用json_serializable pub package满足所有RESTful API的需求,并且效果很好,但是现在我正尝试从Wikipedia序列化内容。

我的问题是响应结构,其中一个键是事先未知的,并且根据返回的页面ID是动态的,这是一个示例:

我只想获取页面的简介部分,我的查询是: https://en.wikipedia.org/w/api.php?action=query&format=json&prop=extracts&redirects=1&exintro=1&explaintext=1&titles=Stack%20Overflow

响应将是:

{
    "batchcomplete": "",
    "query": {
        "pages": {
            "21721040": {
                "pageid": 21721040,
                "ns": 0,
                "title": "Stack Overflow",
                "extract": "Stack Overflow is a privately held website, the flagship site of ......."
            }
        }
    }
}

最终,我只想获取内部的extract字符串,但是在“按我的方式”那里,我的页面ID在pages下。

我无法使用json_serializable package或显式编写JSON导入代码时都无法知道密钥是什么,因此我无法找到对象。有可能吗?

PS,我确实认为我找到了一种需要两次API调用的方法-如果我添加 indexpageids 标志并将其设置为true,i will receive an additional dictionary entry called pageids with the page id numbers as string,则可以使用检索到的字符串在第二个API调用中。

我仍然不知道确切的方法,但是我很确定这是可能的,但是每次发送2个API请求都很昂贵,我想知道是否还有一种更优雅的方法

3 个答案:

答案 0 :(得分:0)

确保使用最新版本的json_serializable。将Map<String, Page>用于键值对:

@JsonSerializable()
class Query {
  final Map<String, Page> pages;

  Query(this.pages);
  factory Query.fromJson(Map<String, dynamic> json) => _$QueryFromJson(json);
  Map<String, dynamic> toJson() => _$QueryToJson(this);
}

只是为了证明它有效,这就是json_serializable生成的内容:

Query _$QueryFromJson(Map<String, dynamic> json) {
  return new Query((json['pages'] as Map<String, dynamic>)?.map((k, e) =>
      new MapEntry(
          k, e == null ? null : new Page.fromJson(e as Map<String, dynamic>))));
}

答案 1 :(得分:0)

您可以获取json键,然后使用该键将值提取为

var response = await http.get(API_ENDPOINT);
var responseJson = json.decode(response.body);
Map<String, dynamic> json =responseJson['query']['pages'];
String pageId = json.keys.toList()[0]; // 0 for first page, you can iterate for multiple pages
firstPage = json[pageId]; 
String title = firstPage["title"];

答案 2 :(得分:0)

如果动态密钥中有另一级动态密钥,您将如何处理?我必须为第二个类编辑生成的json_serializable,以仅使用json而不是生成的json ['key']。

Page _$PageFromJson(Map<String, dynamic> json) {
  return new Page((json as Map<String, dynamic>)?.map((k, e) =>
  new MapEntry(
      k, e == null ? null : new SecondPage.fromJson(e as Map<String, dynamic>))));
}

感觉有更好的方法吗?因为每次我在任何文件中进行更改并运行generator时,生成的代码都会被覆盖。

我是新手,所以我无法对答案进行评分和发表评论。但是boformer的回答对我有所帮助,但后来我遇到了第二个问题。

编辑:我通过反复试验找到了解决方案,使用了:

class Query {
  final Map<String, Map<String, SecondPage>> pages;