如何在颤振中解析复杂的json

Posted

技术标签:

【中文标题】如何在颤振中解析复杂的json【英文标题】:how to parse complex json in flutter 【发布时间】:2019-09-06 16:46:01 【问题描述】:

我无法从复杂的 json 中获取数据,下面是请求中的 json。


   "results":
      "TotalRecordCount":"1",
      "Records":[
         
            "code":"PCK_34333338365C93E2D50DB9C",
            "address":"1 AV KHEIREDDINE PACHA Imm Pacha centre BLOC B tunis Tunis 1000",
            "contact_phone":"99608258"
         
      ],
      "Result":"OK"
   

下面是我制作的模型。

import 'dart:convert';

class Pickup 
  String status;
  List message;
  //Map<String ,dynamic> results;
  Results results;
  Pickup(
    this.status,
     this.message,
     this.results,
  );
  factory Pickup.fromJson(Map<String, dynamic> json) 
    return Pickup(
             status: json["status"] as String,
             results: Results.fromJson(json["results"]),

           );
  


class Results 
  String TotalRecordCount;
  records Records;

  Results(this.TotalRecordCount,this.Records);

  factory Results.fromJson(Map<String, dynamic> json) 
    return Results(
    TotalRecordCount: json["TotalRecordCount"],
    Records:records.fromJson(json["Records"]),

    );
  


class records
  String code;
  String address;
  String contact_phone;

  records(
    this.code,
    this.address,
    this.contact_phone
  );

  factory records.fromJson(Map<String, dynamic> json) 
    return records(
      code: json["code"],
      address: json["address"],
      contact_phone: json["contact_phone"],
    );
  

现在我正在尝试解析记录以获取代码或地址并打印出来。

if (response.statusCode == 200) 
  print(response.body);
  final responseJson = json.decode(response.body);
  var da=Pickup.fromJson(responseJson);
  Results dat=da.results;
  records data=dat.Records;
  print(data.address);

response.body 工作正常,但是当我尝试解析结果或记录时,我得到 'List' is not a subtype of type 'Map' 错误

【问题讨论】:

见flutter.dev/docs/development/data-and-backend/… javiercbk.github.io/json_to_dart 使用在线Json to dart pojo转换器的最佳方式***.com/questions/51901760/… 【参考方案1】:

   "results":
      "TotalRecordCount":"1",
      "Records":[
         
            "code":"PCK_34333338365C93E2D50DB9C",
            "address":"1 AV KHEIREDDINE PACHA Imm Pacha centre BLOC B tunis Tunis 1000",
            "contact_phone":"99608258"
         
      ],
      "Result":"OK"
   

上面的 JSON 文件包含一个“记录”列表,因此它是一个复杂的 JSON。以下是我想对代码做出贡献的修改 -

class Pickup 
  String status;
  List message;
  //Map<String ,dynamic> results;
  Results results;
  Pickup(
    this.status,
     this.message,
     this.results,
  );
  factory Pickup.fromJson(Map<String, dynamic> json) 
    return Pickup(
             status: json["status"] as String,
             results: Results.fromJson(json["results"]),

           );
  

class Results 
  String TotalRecordCount;
  records Records;

  Results(this.TotalRecordCount,this.Records);



    factory Results.fromJson(Map<String, dynamic> json) 
        //since records is a list hence it is parsed separately by creating a 
        //list out of it.  
    



       listOfRecords = (json["Records"] as List)
      .map((i) => records.fromJson(i))
      .toList();


 
    return Results(
    TotalRecordCount: json["TotalRecordCount"],
    Records:listOfRecords //now the list is used here directly
),

    );
  


class records
  String code;
  String address;
  String contact_phone;

  records(
    this.code,
    this.address,
    this.contact_phone
  );

  factory records.fromJson(Map<String, dynamic> json) 
    return records(
      code: json["code"],
      address: json["address"],
      contact_phone: json["contact_phone"],
    );
  

最后,我们可以在任何需要的地方使用它——

if (response.statusCode == 200) 
  print(response.body);
  final responseJson = json.decode(response.body);
  var da = Pickup.fromJson(responseJson);
  Results dat = da.results;
  records data = dat.Records;
  print(data[0].address);  //since records was a list

【讨论】:

【参考方案2】:

我们将解析一个复杂的 JSON,其中包含一些字段和一个对象数组字段。它看起来像这样:


  "title": "Dart Tutorial",
  "description": "Way to parse Json",
  "author": 
    "name": "bezkoder",
    "age": 30
  ,
  "tags": [
    
      "name": "dart",
      "quantity": 12
    ,
    
      "name": "flutter",
      "quantity": 25
    
  ]

我们修改了 Tutorial 类,使它有一个新的 List&lt;Tag&gt; 标签字段。

class Tutorial 
  String title;
  String description;
  User author;
  List<Tag> tags;

  Tutorial(this.title, this.description, this.author, [this.tags]);

  factory Tutorial.fromJson(dynamic json) 
    if (json['tags'] != null) 
      var tagObjsJson = json['tags'] as List;
      List<Tag> _tags = tagObjsJson.map((tagJson) => Tag.fromJson(tagJson)).toList();

      return Tutorial(
        json['title'] as String,
        json['description'] as String,
        User.fromJson(json['author']),
        _tags
      );
     else 
      return Tutorial(
        json['title'] as String,
        json['description'] as String,
        User.fromJson(json['author'])
      );
    
  

  @override
  String toString() 
    return ' $this.title, $this.description, $this.author, $this.tags ';
  

– 在构造方法中,我们使用方括号[this.tags]来指定这个tags数组是一个选项字段。

– 就像我们将 JSON 对象数组解析成 Dart List 的方式一样,我们使用 map()toList() 来获取 List&lt;Tag&gt;

List<Tag> _tags = tagObjsJson.map((tagJson) => Tag.fromJson(tagJson)).toList();

main() 函数现在看起来像这样。

import 'dart:convert';

main() 
  String complexText =
      '"title": "Dart Tutorial", "description": "Way to parse Json", "author": "name": "bezkoder", "age": 30, "tags": ["name": "dart", "quantity": 12, "name": "flutter", "quantity": 25]';

  Tutorial complexTutorial = Tutorial.fromJson(jsonDecode(complexText));

  print(complexTutorial);

运行上面的代码后,你可以看到带有标题、描述、作者、标签数组的结果。

 Dart Tutorial, Way to parse Json,  bezkoder, 30 , [ dart, 12 ,  flutter, 25 ] 

基于:parse complex JSON

【讨论】:

【参考方案3】:

我一定会向你推荐这个网站 json to dart App Quicktype 只是不要忘记在右侧选择 Dart。

你只需将你的 json 放在 la left 中,in 就会给你这样的东西:

// To parse this JSON data, do
//
//     final pickUp = pickUpFromJson(jsonString);

import 'dart:convert';

PickUp pickUpFromJson(String str) => PickUp.fromJson(json.decode(str));

String pickUpToJson(PickUp data) => json.encode(data.toJson());

class PickUp 
    Results results;

    PickUp(
        this.results,
    );

    factory PickUp.fromJson(Map<String, dynamic> json) => new PickUp(
        results: Results.fromJson(json["results"]),
    );

    Map<String, dynamic> toJson() => 
        "results": results.toJson(),
    ;


class Results 
    String totalRecordCount;
    List<Record> records;
    String result;

    Results(
        this.totalRecordCount,
        this.records,
        this.result,
    );

    factory Results.fromJson(Map<String, dynamic> json) => new Results(
        totalRecordCount: json["TotalRecordCount"],
        records: new List<Record>.from(json["Records"].map((x) => Record.fromJson(x))),
        result: json["Result"],
    );

    Map<String, dynamic> toJson() => 
        "TotalRecordCount": totalRecordCount,
        "Records": new List<dynamic>.from(records.map((x) => x.toJson())),
        "Result": result,
    ;


class Record 
    String code;
    String address;
    String contactPhone;

    Record(
        this.code,
        this.address,
        this.contactPhone,
    );

    factory Record.fromJson(Map<String, dynamic> json) => new Record(
        code: json["code"],
        address: json["address"],
        contactPhone: json["contact_phone"],
    );

    Map<String, dynamic> toJson() => 
        "code": code,
        "address": address,
        "contact_phone": contactPhone,
    ;


一开始它会告诉你如何使用它。

// To parse this JSON data, do
//
//     final pickUp = pickUpFromJson(jsonString);

所以当你在你的代码中调用它时,它会是这样的。

  Future<Pickup> getPickup() async 
    var response = await http.get(url);
    return pickUpFromJson(response.body);
  

例如,此代码可以调用 FutureBuilder 或您将代码设置为等待未来的任何位置。

【讨论】:

【参考方案4】:

试试这个:https://flutter.dev/docs/development/data-and-backend/json#serializing-json-using-code-generation-libraries

具体使用json_serializable的部分

【讨论】:

以上是关于如何在颤振中解析复杂的json的主要内容,如果未能解决你的问题,请参考以下文章

如何在颤振中解析json

如何继续在颤振中接收 JSON 数组并解析它?

如何在颤振中解析json?

如何使用我的图像在本地的颤振解析 json 文件中的图像?

颤振 - 在 null 上调用了方法“[]”(解析 json)

在颤振中将请求复杂的json发布到api