Dart 内置了对 Json 解析的支持,可以使用 dart:convert
将给定的 Json String(其 Json 格式合法)转换为带字符串 Key 和动态对象 Value 的 Map。你可以直接将 Json 解析为 Map 使用,也可以将其解析后存放到类型化对象中,使得数据更为结构化且更易于维护。
直接解析和使用
var jsonData = '{ "name" : "Dane", "alias" : "FilledStacks" }';
var parsedJson = json.decode(jsonData);
print('${parsedJson.runtimeType} : $parsedJson');
运行以上代码将输出:
_InternalLinkedHashMap<String, dynamic> : {name: Dane, alias: FilledStacks}
因此,访问解析数据的方式是使用 Key 来查询 Map。具体的做法如下:
...
var name = parsedJson['name'];
var alias = parsedJson['alias'];
print('$name is $alias');
这段代码将输出:
Dane is FilledStacks
解析至对象
更为通用的做法是将这些数据解析到一个专为其建模的类中,而不是直接使用解析后的 Map。这通常是通过 Dart 中的命名构造函数来达成。让我们来将测试数据放入模型 (Model) 中——首先我们将以基本方式定义模型,然后定义命名构造函数:
class User {
String name;
String alias;
User(Map<String, dynamic> data) {
name = data['name'];
alias = data['alias'];
}
}
...
var jsonData = '{ "name" : "Dane", "alias" : "FilledStacks" }';
var parsedJson = json.decode(jsonData);
var user = User(parsedJson);
print('${user.name} is ${user.alias}');
这与访问原始 Map 功能相同,但更易于阅读、理解和维护。除了构造函数之外也不用字符串 Key。这种方式不错,但是只有一个构造函数是种限制,它使 Model 类不是对扩展开放,而是必须进行修改,才能将其它功能添加进去。更通用的做法是定义一个可以设置所有属性的构造函数,并使用命名构造函数显式地使用外部数据来创建 Model:
class User {
final String name;
final String alias;
User({this.name, this.alias});
User.fromJson(Map<String, dynamic> data)
: name = data['name'],
alias = data['alias'];
}
...
var jsonData = '{ "name" : "Dane", "alias" : "FilledStacks" }';
var parsedJson = json.decode(jsonData);
var user = User.fromJson(parsedJson);
print('${user.name} is ${user.alias}');
这更清晰、更明确,并且模型 (Model) 现在更少地依赖传递给它的 Map。但有个问题需要考虑:更复杂的 Json 需要复杂的 Model,你真的想为一个简单的 Model 键入所有这些字段吗?我会这样做,因为我认为从长远来看是值得的。幸运的是其实不必手动编写,有现成的在线工具可以处理:JSON to Dart
把你的 Json 粘贴在左边文本框,右边就会生成对应的 Model。类名总是叫 AutoGenerated,你可以重命名为想要的名称,还可以选择使用私有字段。工具可以生成你要的任何 Json 对象的创建代码。
如果有一天这个网站出于某些原因关闭了。只需要搜索 Json to Dart converter,你就会找到不少类似的工具甚至是 git 仓库。
原文: https://www.filledstacks.com/snippet/how-to-parse-json-in-flutter/
作者:Dane Mackier
编译:码王爷