json - Flutter 使用健全的 null 安全性将多级 JSON 解析为类

标签 json flutter class parsing dart-null-safety

我在Android studio中使用FLutter,将多级JSON解析为一个类。尽管我检查了很多 stackoverflow 帖子,但我找不到解决此问题的方法。 这是我的 JSON

String myJson = '
[
 {
  "sensor":"1234",
  "data":
   [
    {
     "value":"40",
     "reading_time1":"2021-04-10"
    },
    {
     "value":"38",
     "reading_time1":"2021-04-11"
     }
   ]
 },
 {
  "sensor":"1235",
  "data":
   [
    {
     "value":"2",
     "reading_time1":"2021-04-23"
    },
    {
     "value":"39",
     "reading_time1":"2021-04-24"
    }
   ]
 }
] '

这些是我的类,使用 https://javiercbk.github.io/json_to_dart/ 生成。但生成的代码不起作用(不是空安全),所以在阅读了很多帖子后,我想出了这些:

class AllSensorData {

  String sensor="";
  List<Sensordata> sensordata = [];

  AllSensorData({required this.sensor,required this.sensordata});

  AllSensorData.fromJson(Map<String, dynamic> json) {
    sensor = json['sensor'];
    if (json['data'] != null) {
      sensordata = <Sensordata>[];
      json['data'].forEach((v) {
        sensordata.add(new Sensordata.fromJson(v));
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['sensor'] = this.sensor;
    if (this.sensordata != null) {
      data['data'] = this.sensordata.map((v) => v.toJson()).toList();
    }
    return data;
  }

}

class Sensordata {
  String value;
  String reading_time;

  Sensordata({
    required this.value,
    required this.reading_time
  });

  Sensordata.fromJson(Map<String, dynamic> json) :
    value = json['value'],
    reading_time = json['reading_time1'];

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['value'] = this.value;
    data['reading_time'] = this.reading_time;
    return data;
  }
}

现在当我运行时:

var decodedJson = jsonDecode(myJson);
var jsonValue = AllSensorData.fromJson(decodedJson);

错误是:

type 'List<dynamic>' is not a subtype of type 'Map<String, dynamic>'

尽管我怀疑可能还有更多。感谢您的帮助。

最佳答案

对于其他来到这里的人来说,这是一个稍微更通用的答案。

分析器选项

当你有implicit-dynamic时设置为false在您的 analysis_options.yaml 文件中,这可能会使一开始解析 JSON 变得困难。

analyzer:
  strong-mode:
    implicit-casts: false
    implicit-dynamic: false

如何进行种姓

如果您正在使用 JSON 顶层的列表,则可以使用 as List种姓类型:

import 'dart:convert';

void main() {
  final myList = json.decode(myJson) as List;
  for (final item in myList) {
    final name = item['name'] as String? ?? '';
    final age = item['age'] as int? ?? 0;
  }
}

String myJson = '''
[
  {
    "name":"bob",
    "age":22
  },
  {
    "name":"mary",
    "age":35
  }
]
''';

这允许您循环遍历每个项目。 item本身就是dynamic ,但您仍然可以将其视为 Map如果为 null,则为其指定一个默认类型值。

使用 fromJson方法

这是一个使用数据类的示例。 (为简洁起见,省略了导入和 myJson 字符串。)

void main() {
  final myList = json.decode(myJson) as List;
  for (final item in myList) {
    if (item is! Map<String, dynamic>) return; //      <-- interesting part
    final person = Person.fromJson(item);
  }
}

class Person {
  final String name;
  final int age;

  Person(this.name, this.age);

  factory Person.fromJson(Map<String, dynamic> json) {
    final name = json['name'] as String? ?? '';
    final age = json['age'] as int? ?? 0;
    return Person(name, age);
  }
}

除了将 map 传递到 fromJson 之前,这几乎做同样的事情。方法,你检查类型。这使得 Dart 能够安全地提升动态 itemMap<String, dynamic> fromJson 所需的类型参数。

关于json - Flutter 使用健全的 null 安全性将多级 JSON 解析为类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67481137/

相关文章:

ajax - 将 JSON 对象列表发送到 Spring MVC Controller

python - 尝试从 json 解析值时出现类型错误

flutter - 在 Flutter/Dart 中,在条件 if 语句中使用 "=="与 "is"有什么区别

ios - 在 Swift 2 中将 JSON 转换为数组

dart - 我可以像这样在 Dart 中使用泛型吗?

csv - 如何在 flutter 中从设备存储中读取 CSV 文件

c# - 如何从另一个类访问具有 protected 构造函数的类

c# - 保存只读结构化数据的最佳 "place"是什么?

c++ - 俄罗斯方 block :类的布局

ajax - MVC 4 $Ajax JSON 请求返回状态 0,状态文本 : "error"