繁体   English   中英

在颤振/飞镖中解析 JSON

[英]Parsing JSON in flutter/dart

您好 IM 试图解析这种类型的 json:


{
    "records": [
        {
            "id": "recHSxuQBgXAkT9HR",
            "fields": {
                "Entry ID": "00663",
                "Date ID": "12-12",
                "(Gregorian) Year": " ?",
                "(Coptic) Month": "12-Mesori",
                "(Coptic) Day": "14",
                "Event Category": [
                    "Commemoration"
                ],
                "Event Heading": "Heading01",
                "Name 01 - Title": "Mr.",
                "Name 01 - Name in English": "Jhon",            
                "Name 01 - Suffix": "23rd Pa",
                "DayText": "On this day,..",
                "Name 01 - Gender": "Male",
                "Name 01 - Classification": [
                    "08 - Patriarch of Alexandria"
                ],
                "Number of Saints Mentioned": 1,
                "Regnal Number": "I",
                "Apostolic Throne": "385-412",
                "Entry Title": "Commemoration of "
            },
            "createdTime": "2020-04-27T05:30:53.000Z"
        },
        {
            "id": "rec3gTgUKo5Co9Qi3",
            "fields": {
                "Entry ID": "00450",
                "Date ID": "08-Paremoude - D30 - 0450",
                "Century": "1st Century",
                "(Gregorian) Year": "68",
                "(Coptic) Month": "08-Paremoud",
                "(Coptic) Day": "30",
                "Event Category": [
                    "Martyrdom"
                ],
                "Event Heading": "Martyrdom of ",
                "Name 01 - Title": "Saint",
                "Name 01 - Name in English": "Mark",
                "Name 01 - Pronoun": "the",
                "Name 01 - Suffix": "Evangelis",
                "DayText": "On this day 2",
                "Name 01 - Gender": "Male",
                "Name 01 - Classification": [
                    "06 - Apostles Order",
                    "07 - Martyrs Order",
                    "08 - Patriarch of Alexandri"
                ],
                "Number of Saints Mentioned": 1,
                "Entry Title": "Martyrdo of the Evangelist ()                                 "
            },
            "createdTime": "2020-04-27T05:30:53.000Z"
        },

这是我获取记录的方法:

  Future<Record> _getRecords() async {
    var response = await http.get(Uri.encodeFull("url"),
        headers: {
          "Authorization": "**********",
          "Accept": "application/json"
        });

    Record record;
    if(response == 200) {
      var jsonData = json.decode(response.body);
      record = Record.fromJson(jsonData);
    }else{
      print(response.statusCode);
    }


    return record;
  }

我不确定如何格式化记录 class,结束当前从服务器收到 422 错误,任何帮助都会很好,谢谢。我需要为每个阵列单独的 class 吗? 我需要后者将数据放入 ListView ......我也不确定我是否正确包含 API 密钥以进行授权? Tnx

您可以在下面复制粘贴运行完整代码
您可以在完整代码中查看Record class 定义并使用FutureBuilder

代码片段

Record recordFromJson(String str) => Record.fromJson(json.decode(str));
... 
if (response.statusCode == 200) {
  return recordFromJson(jsonString);
...
@override
  void initState() {
    _future = _getRecords();

... 
FutureBuilder(
            future: _future,
            builder: (context, AsyncSnapshot<Record> snapshot) {
              switch (snapshot.connectionState) {

工作演示

在此处输入图像描述

完整代码

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

Record recordFromJson(String str) => Record.fromJson(json.decode(str));

String recordToJson(Record data) => json.encode(data.toJson());

class Record {
  List<RecordElement> records;

  Record({
    this.records,
  });

  factory Record.fromJson(Map<String, dynamic> json) => Record(
        records: List<RecordElement>.from(
            json["records"].map((x) => RecordElement.fromJson(x))),
      );

  Map<String, dynamic> toJson() => {
        "records": List<dynamic>.from(records.map((x) => x.toJson())),
      };
}

class RecordElement {
  String id;
  Fields fields;
  DateTime createdTime;

  RecordElement({
    this.id,
    this.fields,
    this.createdTime,
  });

  factory RecordElement.fromJson(Map<String, dynamic> json) => RecordElement(
        id: json["id"],
        fields: Fields.fromJson(json["fields"]),
        createdTime: DateTime.parse(json["createdTime"]),
      );

  Map<String, dynamic> toJson() => {
        "id": id,
        "fields": fields.toJson(),
        "createdTime": createdTime.toIso8601String(),
      };
}

class Fields {
  String entryId;
  String dateId;
  String gregorianYear;
  String copticMonth;
  String copticDay;
  List<String> eventCategory;
  String eventHeading;
  String name01Title;
  String name01NameInEnglish;
  String name01Suffix;
  String dayText;
  String name01Gender;
  List<String> name01Classification;
  int numberOfSaintsMentioned;
  String regnalNumber;
  String apostolicThrone;
  String entryTitle;
  String century;
  String name01Pronoun;

  Fields({
    this.entryId,
    this.dateId,
    this.gregorianYear,
    this.copticMonth,
    this.copticDay,
    this.eventCategory,
    this.eventHeading,
    this.name01Title,
    this.name01NameInEnglish,
    this.name01Suffix,
    this.dayText,
    this.name01Gender,
    this.name01Classification,
    this.numberOfSaintsMentioned,
    this.regnalNumber,
    this.apostolicThrone,
    this.entryTitle,
    this.century,
    this.name01Pronoun,
  });

  factory Fields.fromJson(Map<String, dynamic> json) => Fields(
        entryId: json["Entry ID"],
        dateId: json["Date ID"],
        gregorianYear: json["(Gregorian) Year"],
        copticMonth: json["(Coptic) Month"],
        copticDay: json["(Coptic) Day"],
        eventCategory: List<String>.from(json["Event Category"].map((x) => x)),
        eventHeading: json["Event Heading"],
        name01Title: json["Name 01 - Title"],
        name01NameInEnglish: json["Name 01 - Name in English"],
        name01Suffix: json["Name 01 - Suffix"],
        dayText: json["DayText"],
        name01Gender: json["Name 01 - Gender"],
        name01Classification:
            List<String>.from(json["Name 01 - Classification"].map((x) => x)),
        numberOfSaintsMentioned: json["Number of Saints Mentioned"],
        regnalNumber:
            json["Regnal Number"] == null ? null : json["Regnal Number"],
        apostolicThrone:
            json["Apostolic Throne"] == null ? null : json["Apostolic Throne"],
        entryTitle: json["Entry Title"],
        century: json["Century"] == null ? null : json["Century"],
        name01Pronoun: json["Name 01 - Pronoun"] == null
            ? null
            : json["Name 01 - Pronoun"],
      );

  Map<String, dynamic> toJson() => {
        "Entry ID": entryId,
        "Date ID": dateId,
        "(Gregorian) Year": gregorianYear,
        "(Coptic) Month": copticMonth,
        "(Coptic) Day": copticDay,
        "Event Category": List<dynamic>.from(eventCategory.map((x) => x)),
        "Event Heading": eventHeading,
        "Name 01 - Title": name01Title,
        "Name 01 - Name in English": name01NameInEnglish,
        "Name 01 - Suffix": name01Suffix,
        "DayText": dayText,
        "Name 01 - Gender": name01Gender,
        "Name 01 - Classification":
            List<dynamic>.from(name01Classification.map((x) => x)),
        "Number of Saints Mentioned": numberOfSaintsMentioned,
        "Regnal Number": regnalNumber == null ? null : regnalNumber,
        "Apostolic Throne": apostolicThrone == null ? null : apostolicThrone,
        "Entry Title": entryTitle,
        "Century": century == null ? null : century,
        "Name 01 - Pronoun": name01Pronoun == null ? null : name01Pronoun,
      };
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  Future<Record> _future;

  Future<Record> _getRecords() async {
    /*var response = await http.get(Uri.encodeFull("url"),
        headers: {
          "Authorization": "**********",
          "Accept": "application/json"
        });
*/
    String jsonString = '''
    {
    "records": [
        {
            "id": "recHSxuQBgXAkT9HR",
            "fields": {
                "Entry ID": "00663",
                "Date ID": "12-12",
                "(Gregorian) Year": " ?",
                "(Coptic) Month": "12-Mesori",
                "(Coptic) Day": "14",
                "Event Category": [
                    "Commemoration"
                ],
                "Event Heading": "Heading01",
                "Name 01 - Title": "Mr.",
                "Name 01 - Name in English": "Jhon",            
                "Name 01 - Suffix": "23rd Pa",
                "DayText": "On this day,..",
                "Name 01 - Gender": "Male",
                "Name 01 - Classification": [
                    "08 - Patriarch of Alexandria"
                ],
                "Number of Saints Mentioned": 1,
                "Regnal Number": "I",
                "Apostolic Throne": "385-412",
                "Entry Title": "Commemoration of "
            },
            "createdTime": "2020-04-27T05:30:53.000Z"
        },
        {
            "id": "rec3gTgUKo5Co9Qi3",
            "fields": {
                "Entry ID": "00450",
                "Date ID": "08-Paremoude - D30 - 0450",
                "Century": "1st Century",
                "(Gregorian) Year": "68",
                "(Coptic) Month": "08-Paremoud",
                "(Coptic) Day": "30",
                "Event Category": [
                    "Martyrdom"
                ],
                "Event Heading": "Martyrdom of ",
                "Name 01 - Title": "Saint",
                "Name 01 - Name in English": "Mark",
                "Name 01 - Pronoun": "the",
                "Name 01 - Suffix": "Evangelis",
                "DayText": "On this day 2",
                "Name 01 - Gender": "Male",
                "Name 01 - Classification": [
                    "06 - Apostles Order",
                    "07 - Martyrs Order",
                    "08 - Patriarch of Alexandri"
                ],
                "Number of Saints Mentioned": 1,
                "Entry Title": "Martyrdo of the Evangelist ()                                 "
            },
            "createdTime": "2020-04-27T05:30:53.000Z"
        }
        ]
}
    ''';

    var response = http.Response(jsonString, 200);

    if (response.statusCode == 200) {
      return recordFromJson(jsonString);
    } else {
      print(response.statusCode);
    }
  }

  @override
  void initState() {
    _future = _getRecords();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: FutureBuilder(
            future: _future,
            builder: (context, AsyncSnapshot<Record> snapshot) {
              switch (snapshot.connectionState) {
                case ConnectionState.none:
                  return Text('none');
                case ConnectionState.waiting:
                  return Center(child: CircularProgressIndicator());
                case ConnectionState.active:
                  return Text('');
                case ConnectionState.done:
                  if (snapshot.hasError) {
                    return Text(
                      '${snapshot.error}',
                      style: TextStyle(color: Colors.red),
                    );
                  } else {
                    return ListView.builder(
                        itemCount: snapshot.data.records.length,
                        itemBuilder: (context, index) {
                          return Card(
                              elevation: 6.0,
                              child: Padding(
                                padding: const EdgeInsets.only(
                                    top: 6.0,
                                    bottom: 6.0,
                                    left: 8.0,
                                    right: 8.0),
                                child: Row(
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: <Widget>[
                                    Text(
                                      snapshot.data.records[index].fields
                                          .eventHeading,
                                    ),
                                    Spacer(),
                                    Text(
                                      snapshot.data.records[index].fields
                                          .name01NameInEnglish,
                                    ),
                                  ],
                                ),
                              ));
                        });
                  }
              }
            }));
  }
}

服务器端或请求应该有更多导致 422 错误。 您可能想检查它们。

要回答您的问题,由于数据是Record的列表,因此_getRecords function 应该更像这样。

Future<List<Record>> _getRecords() async {
  var response = await http.get(
    Uri.encodeFull("url"),
    headers: {
      "Authorization": "**********",
      "Accept": "application/json",
    },
  );

  List<Record> records;

  if (response.statusCode == 200) {
    var jsonData = json.decode(response.body) ?? [];
    records = jsonData.map(Record.fromJson).toList();
  } else {
    print(response.statusCode);
  }

  return records;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM