flutter中老生常谈的json序列化操作json_serializable和json_annotation以及插件使用

原创文章
声明:作者声明此文章为原创,未经作者同意,请勿转载,若转载,务必注明本站出处,本平台保留追究侵权法律责任的权利。
全栈老韩
全栈工程师,擅长iOS App开发、前端(vue、react、nuxt、小程序&Taro)开发、Flutter、React Native、后端(midwayjs、golang、express、koa)开发、docker容器、seo优化等。

相信大家在移动端的开发中,不管是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插件,提高开发效率。
android studio flutter 插件
上面截图中就是快速的json到class的插件,大家可以根据红色框去安装到Android studio中。
之后,就可以在创建dart文件时,从鼠标菜单中找到它:
json to dart menu

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

这个插件确实提升了开发效率,大家可以试试。

以上,希望对大家有所帮助。

暂无评论,快来发表第一条评论吧