在前一篇我们已经可以在Flutter中同服务器进行交互了,但是那时我们是通过String来接收的,即可以拿到json格式的数据,那么怎么来解析成实体对象呢?
1. 手动解析:借助于dart的内置库(dart:convert)
dart:convert中有俩个top-level function:jsonDecode()、jsonEncode(),分别用来解析json和生成json。
给定一段json:
1
2
3
4
5
6 1{
2 "name": "David",
3 "age": 24
4}
5
6
然后我们来看示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 1import 'dart:convert'; //引入dart:convert内置库
2
3//手动编码创建Person类
4class Person {
5 String name;
6 int age;
7
8 Person({this.name, this.age});
9
10 Person.fromJson(Map<String, dynamic> json):
11 name = json['name'],
12 age = json['age'];
13
14 Map<String, dynamic> toJson() => {'name': name, 'age': age};
15}
16
17
18void testJson() {
19 String json = '''{"name": "David", "age": 24}'''; //通过'''来定义json,不需使用转义字符
20 Map<String, dynamic> personMap = jsonDecode(json); //解析json
21 Person person = Person.fromJson(personMap); //转换成对象
22 person.name = "lisi";
23 person.age = 25;
24 String json2 = jsonEncode(person.toJson()); //将对象编码成json表示形式
25 print('$json2');
26}
27
28
这种方式很容易理解,应付简单的json毫无压力。但是实际开发中,大多数情况下我们需要处理复杂的json,比如json对象嵌套,这种情况下再使用这种方式就显示特别麻烦了,这种时候就需要下面这种方式了
2. 使用json_serializable库及相关插件
-
修改pubspec.yaml文件,添加依赖库:
1
2
3
4
5
6
7
8
9 1dependencies:
2 json_annotation: ^2.0.0
3
4dev_dependencies:
5
6 build_runner: ^1.0.0
7 json_serializable: ^2.0.0
8
9
-
点击Packages get,拉取依赖
-
新建user.dart文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 1//第一步:导入json_annotation.dart
2import 'package:json_annotation/json_annotation.dart';
3
4//第二步:指定插件生成的中间代码文件名
5part 'user.g.dart';
6
7//第三步:使用JsonSerializable注解表明该类可json序列化
8@JsonSerializable()
9class User {
10
11 String name;
12 String email;
13
14 User(this.name, this.email);
15
16 // 同时工厂构造器和具名构造器 调用_$【类名】FromJson(json)
17 factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
18
19 // 定义toJson函数,调用_$【类名】ToJson(this);
20 Map<String, dynamic> toJson() => _$UserToJson(this);
21
22}
23
24
这个时候呢,编译器应该会提示相关语法错误,这是正常的。我们还有最后一步:
在控制台输入以下命令:
1
2
3 1flutter pub run build_runner watch
2
3
会产生以下变化:
这个user.g.dart文件就是插件为我们生成的,并且之前的语法报错也会消失。不知道你有没有发现,这个命令运行之后并没有终止,意味着我们如果改变类的结构,比如添加个属性,user.g.dart也是及时改变。
当然这最后一步还有一个可替代的命令:
1
2
3 1flutter pub run build_runner build
2
3
这个只会编译一次就停止了,如果对类的结构有修改,需要再次执行此命令。
- @JsonKey
这个注解的作用就类似于gson中的@SerializedName。如:
1
2
3
4 1@JsonKey(name: 'create_time')
2int createTime;
3
4
原始json的key是“create_time”,如果不使用@JsonKey注解,那么此处我们需要将该属性声明为create_time,但是这是不符合我们的命名规范的,所以我们可以通过此注解进行重命名。
- 使用AndroidStudio中的插件:
然后在需要生成对应类的时候:
- 使用在线dart生成工具:https://javiercbk.github.io/json_to_dart/