flutter中老生常谈的json序列化操作json_serializable和json_annotation以及插件使用
相信大家在移动端的开发中,不管是iOS还是Android中都有json序列化的操作,比如MJ的json序列化,那么flutter中同样也是有对应的json序列化和反序列化操作。
这里做一个回顾介绍,温故知新一下。
一、flutter中的json serializable
在flutter中需要依赖2个库去实现:
- json_serializable
- json_annotation
这2个package需要一起使用,具体的使用可以在对应的pub.dev上看到:
https://pub.dev/packages/json_serializable
https://pub.dev/packages/json_annotation
具体安装方法:
terminal
dart pub add dev:json_serializable
terminal
dart pub add json_annotation
二、具体使用
当我们在请求接口的时候,可以把json数据转成对应的class对象使用。
比如:
user.json
{
"user_id" : "1234",
"nick_name" : "Tom",
"age": 1,
"right": {
"vip" : 1
}
}
这里我们使用了嵌套的json结构,即map中还有map结构,所以我们需要定义2个class,然后在user的class中包含right的class,这个是常见的结构形式。
2.1 定义Right的class
right.dart
import 'package:json_annotation/json_annotation.dart';
// 1. 一定要加一个文件引入,这个part引入的.g.dart文件是在后面的dart命令中生成的,而且和class在同一个目录中。
part 'right.g.dart';
// 2. 需要添加 @JsonSerializable()
@JsonSerializable()
class Right {
final int? vip;
Right({
this.vip,
});
// 3. 下面的2个方法需要手动写上,_$RightFromJson和_$RightToJson是在后面的dart命令中生成的,暂时的语法报错,先不要管。(前缀都是默认你的class名字的首字母大写驼峰写法:Right, 后缀统一为fromJson和toJson)
factory Right.fromJson(Map<String, dynamic> json) =>
_$RightFromJson(json);
Map<String, dynamic> toJson() => _$RightToJson(this);
}
2.2 定义User的class
user.dart
import 'package:json_annotation/json_annotation.dart';
import 'package:xxx/modules/app/beans/right.dart';
// 1. 声明后续dart命令会生成的文件
part 'user.g.dart';
// 2. 需要添加 @JsonSerializable()
@JsonSerializable()
class User {
// 3. 使用别名,那么要使用@JsonKey去声明原始json中的字段
@JsonKey(name: "user_id")
final String? userId;
@JsonKey(name: "nick_name")
final String? nickName;
final int? age;
// 4. 权益class
final Right? right;
User({
this.userId,
this.nickName,
this.age,
this.right,
});
// 5. fromJson和toJson方法
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}
2.3 json转class
比如从接口获取到了json数据,然后我们就可以直接使用user class去转化。
xxx.dart
...
final res = response as Map<String, dynamic>?;
if (res == null) return null;
final user = User.fromJson(res);
...
2.4 执行dart生成命令
以上2个class声明之后,就可以执行dart命令,去生成对应的xxx.g.dart文件。
(终端命令,在根目录下执行,会自动查找所有有@JsonSerializable()的class,然后生成对一个的.g.dart文件)
terminal
dart run build_runner build
以上的基础结构其实已经满足了简单的json序列化操作。
三、进阶操作
3.1 在class中声明一个非json字段
还是用上述的user.dart举例,意思是指,如果在user中增加一个自定义的字段(不在原始json数据中),比如想增加一个是否选中的bool字段:isSelected,那么这个属性就不需要从json中转化。
可以这么做:
user.dart
...
// 1. 在JsonKey中设置这2个属性为false,表示这个字段不需要从json数据中转,也不需要从class中转的Map中。
// 2. 这里不用final声明,表示user这个class的isSelected字段可以在使用时进行修改。
@JsonKey(includeFromJson: false, includeToJson: false)
bool isSelected = true;
...
3.2 一个class extends 另一个序列化class
依然拿上面的user.dart举例,现在有一个class,拥有比user class更多的信息,也就是多了一个或者多个字段,然后是在另外一个接口中请求到。
我来详细的举例,比如上面的user,代表的是通用的用户信息,但是现在有一个场景,代表访客,那么这个访客可以有一个访问次数的信息,当然这个访客也拥有通用的用户信息。直接举例:
visitor.json
{
"user_id" : "1234",
"nick_name" : "Tom",
"age": 1,
"right": {
"vip" : 1
},
# 这里比user信息多一个字段
"visit_count" : 3
}
那么visitor应该extendsuser,看下面的代码,我在代码中进行注释。
visitor.dart
// 1. 必须引入user class
import 'package:xxx/modules/app/beans/user.dart';
// 2. 这个文件虽然没有用到right class,但是也必须引入。
// 否则dart命令将找不到嵌套的right的class声明。
import 'package:xxx/modules/app/beans/right.dart';
// 3. 同样需要引入后续命令生成的.g.dart
part 'visitor.g.dart';
// 4. 这里需要extends user
@JsonSerializable()
class Visitor extends User {
@JsonKey(name: "visit_count")
final int? visitCount;
Visitor(this.visitCount);
// 5. 依然需要from json 和 to json方法
factory Visitor.fromJson(Map<String, dynamic> json) =>
_$VisitorFromJson(json);
@override
Map<String, dynamic> toJson() => _$VisitorToJson(this);
}
上面的代码解释应该很清晰吧,每次新增一个JsonSerializable的class,都需要执行2.4的dart命令。
3.3 使用Android Studio插件
上面的基本使用大家应该都知道了,但是每次都要写非常多的样式代码,实在是比较费劲,所以有大佬写了Androi Studio插件,提高开发效率。

上面截图中就是快速的json到class的插件,大家可以根据红色框去安装到Android studio中。
之后,就可以在创建dart文件时,从鼠标菜单中找到它:

从下面的截图中,你应该可以知道如何把json数据粘贴到json框中,声明class名称,然后点击生成。

这个插件确实提升了开发效率,大家可以试试。
以上,希望对大家有所帮助。
暂无评论,快来发表第一条评论吧