因为Flutter中的dart不支持反射,所以没有类似 GSON/Jackson/Netonsoft.Net 那种类库,不支持反射的原因是为了支持 tree shake,减少App体积。
下面介绍如果使用json_serializable
序列化:
安装依赖
flutter pub add json_annotation
flutter pub add build_runner --dev
flutter pub add json_model --dev # 用于从JSON文件生成dart类
flutter pub add json_serializable --dev
方式1 JSON文件生成实体类
使用步骤
根据JSON文件自动创建实体类
- 项目根目录创建 jsons 文件夹
- 创建JSON文件(文件内容示例参考下面)
- 执行命令生成 model:
flutter pub run json_model src=jsons
jsons/user.json
{
"name":"wendux",
"father":"$user", //可以通过"$"符号引用其它model类, 这个是引用User类
"friends":"$[]user", // 可以通过"$[]"来引用数组
"keywords":"$[]String", // 同上
"age?": 20, // 年龄,可能为null
"license?": { // 该项目的开源许可证
"key": "mit",
"name": "MIT License",
"spdx_id": "MIT",
"url": "https://api.github.com/licenses/mit",
"node_id": "MDc6TGljZW5zZW1pdA=="
}
}
JSON文件特性
- 可以通过 $ 符号引用其他model类, 比如引用
User
类:"father": "$user"
- 可以通过 $[] 引用输入, 比如
"array": "$[]User"
或者"friends": "$[]String"
- 可为空字段:
"age?": 20
- 使用 json_annotation中的所有注解, 比如:
{
"@JsonKey(name: '+1') int?": "loved", //将“+1”映射为“loved”
"name":"wendux",
"age?":20
}
- 可以在JSON文件增加
@meta
信息定制dart类生成规则:
{
"@meta": {
"import": [ // 生成的Dart文件中需要额外import的文件,可以有多个
"test_dir/profile.dart"
],
"comments": { // Json文件中相应字段的注释
"name": "名字"
},
"nullable": true, // 是否生成的model字段都是可空的,如果为false,则字段为late
"ignore": false // json->dart时是否跳过当前文件,默认为false,设为true时,生成时则会跳过本json文件
},
"name":"wendux",
"age?":20
}
在实际ubuntu环境, 发现文件夹名必须是
Jsons
. 自己根据实际情况调整.
方式2 手动编写实体类属性
手动编写实体类, 然后自动生成 fromJson
和 toJson
方法.
编写实体类
user.dart
import 'package:json_annotation/json_annotation.dart';
/// This allows the `User` class to access private members in
/// the generated file. The value for this is *.g.dart, where
/// the star denotes the source file name.
part 'user.g.dart';
/// An annotation for the code generator to know that this class needs the
/// JSON serialization logic to be generated.
@JsonSerializable()
class User {
User(this.name, this.email, this.age);
String name;
String email;
@JsonKey(defaultValue: 18)
int age;
/// A necessary factory constructor for creating a new User instance
/// from a map. Pass the map to the generated `_$UserFromJson()` constructor.
/// The constructor is named after the source class, in this case, User.
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
/// `toJson` is the convention for a class to declare support for serialization
/// to JSON. The implementation simply calls the private, generated
/// helper method `_$UserToJson`.
Map<String, dynamic> toJson() => _$UserToJson(this);
}
info
如果有嵌套类,比如 User.dart
有个字段 final Address address;
,这个Address
是个类,那就需要把 User
类的注解 @JsonSerializable()
改成 @JsonSerializable(explicitToJson: true)
.
执行命令生成
flutter pub run build_runner build # 执行该命令生成缺失的方法
flutter pub run build_runner watch # 或者执行该命令监听文件变化自动生成