2021年4月编辑补充
参考:https://flutterchina.club/json/#code-generation JSON和序列化
使用代码生成库序列化JSON
尽管还有其他库可用,但在本教程中,我们使用了json_serializable package包。 它是一个自动化的源代码生成器,可以为我们生成JSON序列化模板。
由于序列化代码不再由我们手写和维护,我们将运行时产生JSON序列化异常的风险降至最低。
在项目中设置json_serializable
要包含json_serializable
到我们的项目中,我们需要一个常规和两个开发依赖项。简而言之,开发依赖项是不包含在我们的应用程序源代码中的依赖项。
通过此链接可以查看这些所需依赖项的最新版本 。
pubspec.yaml
dependencies:
# Your other regular dependencies here
json_annotation: ^2.0.0
dev_dependencies:
# Your other dev_dependencies here
build_runner: ^1.0.0
json_serializable: ^2.0.0
在您的项目根文件夹中运行 flutter packages get
(或者在编辑器中点击 “Packages Get”) 以在项目中使用这些新的依赖项.
以json_serializable的方式创建model类
让我们看看如何将我们的User
类转换为一个json_serializable
。为了简单起见,我们使用前面示例中的简化JSON model。
user.dart
import 'package:json_annotation/json_annotation.dart';
// user.g.dart 将在我们运行生成命令后自动生成
part 'user.g.dart';
///这个标注是告诉生成器,这个类是需要生成Model类的
@JsonSerializable()
class User{
User(this.name, this.email);
String name;
String email;
//不同的类使用不同的mixin即可
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}
有了这个设置,源码生成器将生成用于序列化name
和email
字段的JSON代码。
如果需要,自定义命名策略也很容易。例如,如果我们正在使用的API返回带有snake_case的对象,但我们想在我们的模型中使用lowerCamelCase, 那么我们可以使用@JsonKey标注:
/// Tell json_serializable that "registration_date_millis" should be
/// mapped to this property.
@JsonKey(name: 'registration_date_millis')
final int registrationDateMillis;
运行代码生成程序
json_serializable
第一次创建类时,您会看到与下图类似的错误。
这些错误是完全正常的,这是因为model类的生成代码还不存在。为了解决这个问题,我们必须运行代码生成器来为我们生成序列化模板。
There are two ways of running the code generator. 有两种运行代码生成器的方法:
一次性生成
通过在我们的项目根目录下运行flutter packages pub run build_runner build
,我们可以在需要时为我们的model生成json序列化代码。 这触发了一次性构建,它通过我们的源文件,挑选相关的并为它们生成必要的序列化代码。
虽然这非常方便,但如果我们不需要每次在model类中进行更改时都要手动运行构建命令的话会更好。
持续生成
使用watcher可以使我们的源代码生成的过程更加方便。它会监视我们项目中文件的变化,并在需要时自动构建必要的文件。我们可以通过flutter packages pub run build_runner watch
在项目根目录下运行来启动watcher。
只需启动一次观察器,然后并让它在后台运行,这是安全的。
使用json_serializable模型
要通过json_serializable
方式反序列化JSON字符串,我们不需要对先前的代码进行任何更改。
Map userMap = JSON.decode(json);
var user = new User.fromJson(userMap);
序列化也一样。调用API与之前相同。
String json = JSON.encode(user);
有了json_serializable
,我们可以在User
类上忘记任何手动的JSON序列化 。源代码生成器创建一个名为user.g.dart
的文件,它具有所有必需的序列化逻辑。 现在,我们不必编写自动化测试来确保序列化的正常工作 - 这个库会确保序列化工作正常。
-------------------------------- 不华丽的分割线 --------------------------------
下面的方法过时了
下面介绍两种方法:
一、使用在线工具,生成再拷贝
https://javiercbk.github.io/json_to_dart/
这个很简单,就不多说了。
二、使用freezed
https://pub.dev/packages/freezed
最好再结合VSCode的插件 Freezed (我使用VSCode)AndroidStudio上也有类似的插件。
安装:pubspec.yaml中修改如下
dependencies:
flutter:
sdk: flutter
freezed_annotation:
dev_dependencies:
flutter_test:
sdk: flutter
json_serializable:
build_runner:
freezed:
安装好Freezed插件后
方法:打开命令面板 输入 Freezed
选择命令: Freezed:Generate a new Freezed class
依次输入类名、是否序列化(Y)
修改相应的名称,再加入属性,这里可以选择从JSON中拷贝生成。
再从命令面板中,操作同上 执行
Freezed:Build with build_runner
执行结束后,就OK了。
下次再修改了 item.dart 文件后,再次执行 build_runner命令就可以了。