Flutter 中的 JSON序列化
文章目录
使用 dart:convert手动序列化JSON
内连序列化JSON
String json = "{\"name\": \"John Smith\",\"email\":\"john@example.com\"}";
//解析字符串并返回结果Json对象
var userObject = jsonDecode(json);
print("name=${user['name']}");
jsonDecode直到运行时才知道值的类型。 通过这种方法,我们失去了大部分静态类型语言特性:类型安全、自动补全和最重要的编译时异常。这样一来,我们的代码可能会变得非常容易出错。
例如,当我们访问name
或email
字段时,我们输入的很快,导致字段名打错了。但由于这个JSON在map结构中,所以编译器不知道这个错误的字段名(译者语:所以编译时不会报错)
在模型类中序列化JSON
引入一个简单的模型类(model class)来解决前面提到的问题
class User {
final String name;
final String email;
User(this.name, this.email);
User.fromJson(Map<String, dynamic> json)
: name = json['name'],
email = json['email'];
Map<String, dynamic> toJson() => {
'name': name,
'email': email,
};
}
使用:
var userData = User.fromJson(userObject);
print("name = ${userData.name}");
使用代码生成库序列化JSON
使用json_serializable生成序列化json的代码
在项目中设置json_serializable
pubspec.yaml
dependencies:
json_serializable: ^4.1.0
dev_dependencies:
build_runner: ^1.0.0
在您的项目根文件夹中运行 flutter pub get(或者在编辑器中点击 “Pub get”)
以json_serializable的方式创建model类
import 'package:json_annotation/json_annotation.dart';
//手动编写, user.g.dart 将在我们运行生成命令后自动生成
part 'user.g.dart';
@JsonSerializable()
class User {
final String name;
final String email;
final DateTime? dateOfBirth;
User(this.name, this.email, this.dateOfBirth);
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}
如果需要,自定义命名策略也很容易。例如,如果我们正在使用的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;
这时发现_$UserFromJson(json)和_ $UserToJson(this)报红,为了解决这个问题,我们必须运行代码生成器来为我们生成序列化模板
运行代码生成器
有两种运行代码生成器的方法:
一次性生成
在您的项目目录中运行以下命令
flutter pub run build_runner build
我们可以在需要时为我们的model生成json序列化代码。 这触发了一次性构建,它通过我们的源文件,挑选相关的并为它们生成必要的序列化代码
持续生成
在您的项目目录中运行以下命令
flutter pub run build_runner watch
使用_watcher_可以使我们的源代码生成的过程更加方便。它会监视我们项目中文件的变化,并在需要时自动构建必要的文件
在part ‘user.g.dart’ 生成的代码:
part of 'user.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
User _$UserFromJson(Map<String, dynamic> json) {
return User(
json['name'] as String,
json['email'] as String,
json['dateOfBirth'] == null
? null
: DateTime.parse(json['dateOfBirth'] as String),
);
}
Map<String, dynamic> _$UserToJson(User instance) => <String, dynamic>{
'name': instance.name,
'email': instance.email,
'dateOfBirth': instance.dateOfBirth?.toIso8601String(),
};
使用和上面的一样:
var userObject = jsonDecode(json);
var userData = User.fromJson(userObject);
print("name = ${userData.name}");
参考: JSON和序列化
json处理