现在大多数接口返回的数据都是json格式,在面向对象的开发过程中,基本上都需要转换为Model模型,方便在开发中使用。在Android开发中json字符串转Model对象,可以使用Gson、FastJson等,但在Flutter中确没有这么方便。在Flutter中,提供了dart.convert以及json.dart来解析json字符串,但转换后Map对象,要转换为Model对象还需要进一步处理。
2.1 定义Model对象以及转换方法
class Photo {
final int albumId;
final String title;
Photo({required this.albumId, required this.title});
factory Photo.fromJson(Map json) {
return Photo(
albumId: json['albumId'] as int, title: json['title'] as String);
}
Map toJson() {
return {'albumId': albumId, 'title': title};
}
@override
String toString() {
return 'Photo{albumId: $albumId, title: $title}';
}
}
2.2 测试代码
void main() {
var jsonStr = "{\"albumId\": 10001, \"title\": \"this is photo title\"}";
//使用框架自带json解析工具
var jsonMap = jsonDecode(jsonStr);
var photo = Photo.fromJson(jsonMap);
print(photo.toString());
}
手动将Json转换为Model对象略显麻烦,对象属性较少的情况还是能够接受的。
手动写fromJson和toJson方法略显麻烦,这里官方提供了json_serializable,自动帮我们完成相关方法的实现。
3.1 配置
进入pub.dev官网,查看json_serializable的集成文档,提到需要 package:json_annotation,但是没有明确的说明,需要查看example
进入demo,根据要求,在pubspec.yaml中添加
dependencies:
json_annotation: ^4.4.0
dev_dependencies:
build_runner: ^2.0.0
json_serializable: ^6.1.0
添加完package后,确没有说应该添加什么内容,查看example.dart,里面的内容也是完整的,自己写的时候确不知道怎么下手。接下来就一步一步的尝试。
第一步:
新建example.dart,并新建Animal类,添加@JsonSerializable()注解,如下所示:
@JsonSerializable()
class Animal{
final String name;
final String age;
Animal(this.name, this.age);
}
第二步:执行命令
如果是flutter项目,需要执行以下命令生产example.g.dart文件。
flutter packages pub run builder_runner build
在AndroidStudio的Terminal中,执行上面的命令,得到以下信息
[INFO] Generating build script...
[INFO] Generating build script completed, took 342ms
[INFO] Initializing inputs
[INFO] Reading cached asset graph...
[INFO] Reading cached asset graph completed, took 63ms
[INFO] Checking for updates since last build...
[INFO] Checking for updates since last build completed, took 618ms
[INFO] Running build...
[INFO] Running build completed, took 16ms
[INFO] Caching finalized dependency graph...
[INFO] Caching finalized dependency graph completed, took 41ms
[INFO] Succeeded after 67ms with 0 outputs (0 actions)
第三步:添加fromJson和toJson方法,在执行build命令
@JsonSerializable()
class Animal{
final String name;
final String age;
Animal(this.name, this.age);
factory Animal.fromJson(Map json) => _$AnimalFromJson(json);
Map toJson() => _$AnimalToJson(this);
}
执行结果:
......
[INFO] Succeeded after 948ms with 1 outputs (2 actions)
却没有找到任何的输出的example.g.dart文件。
第四步:添加part ‘example.g.dart’; 再运行build命令:
part 'example.g.dart';
@JsonSerializable()
class Animal{
final String name;
final String age;
Animal(this.name, this.age);
factory Animal.fromJson(Map json) => _$AnimalFromJson(json);
Map toJson() => _$AnimalToJson(this);
}
结果:终于生产了example.g.dart文件。原来part 'example.g.dart’才是这里的关键。
Animal _$AnimalFromJson(Map json) => Animal(
json['name'] as String,
json['age'] as String,
);
Map _$AnimalToJson(Animal instance) => {
'name': instance.name,
'age': instance.age,
};
可以自动生成的结果和我们手动写的基本一致。到这里感觉官网的文档说明真没有说清楚,到底哪些是应该添加,只看demo不一步一步的尝试是不知道**.g.dart是如何生产的。
以下内容都是必须添加的,如果后续json_serializable的版本升级后有变动,需根据最新的方法来完成。
第一步:在pubspec.yaml添加package
dependencies:
json_annotation: ^4.4.0
dev_dependencies:
build_runner: ^2.0.0
json_serializable: ^6.1.0
第二步:添加实体类,必须写构造方法
class *{
finla String field1;
final String field2;
*(this.field1,this.field2);
}
第三步:添加注解和part 'x.g.dart’
part '*.g.dart'
@JsonSerializable()
class *{
finla String field1;
final String field2;
*(this.field1,this.field2);
}
添加part '*.g.dart’会报错,这里可以先不用管,运行后面的build命令后会消除。
第四步:运行build命令
flutter packages pub run build_runner build
运行完成该命令后会自动生产*.g.dart文件,里面有相关的fromJson和toJson方法。
第五步:在实体中添加fromJson工厂构造函数和toJson方法
part '*.g.dart'
@JsonSerializable()
class *{
finla String field1;
final String field2;
*(this.field1,this.field2);
factroy *.fromJson(Map json) => _*FromJson(json)
Map toJson() => _*ToJson(this)
}
如果后面的开发过程中,Model中有字段的添加、删除或者类型修改,只需要重新执行一次build命令即可。