JSON和序列化
2019-08-14 本文已影响0人
柳源居士
flutter 里面因为tree shaking的使用,并不提供类似GSON / Jackson / Moshi等的Json转换库。因此才需要使用手动序列化或者自动序列化。
tree shaking
tree-shaking可以理解为通过工具"摇"我们的JS文件,将其中用不到的代码"摇"掉,是一个性能优化的范畴。
json 对象是通过一个字符串来赋值。
如:
var json='{"name":"dart","type":"language"}';
- flutter 手动序列化
手动JSON序列化是指使用flutter内置的库 dart:convert 中内置的JSON解码器。它将原始JSON字符串传递给JSON.decode() 方法,然后在返回的Map<String, dynamic>中查找所需的值。 它没有外部依赖或其它的设置,对于小项目很方便。
//把json对象解码成数组对象
var data = jsonDecode(json);
String result = data['name'];
- 在模型类中序列化JSON
把json对应成model,然后添加fromJson的构造方法和toJson的方法,用来转换。
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,
};
}
使用方式:
Map userMap = jsonDecode(json);
var user = new User.fromJson(userMap);
print('Howdy, ${user.name}!');
print('We sent the verification link to ${user.email}.');
- 自动序列化
当项目变大,手动序列化难以维护或者容易出错,就需要自动序列化。
代码生成功能的JSON序列化是指通过外部库为您自动生成序列化模板。它需要一些初始设置,并运行一个文件观察器,从您的model类生成代码。
- 设置依赖
pubspec.yaml中添加依赖:
- 设置依赖
dependencies:
json_annotation: ^2.0.0
dev_dependencies:
build_runner: ^1.0.0
json_serializable: ^2.0.0
-
- 添加model,并添加注解
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); }
- 设置bulid方式
- 手动方式:一次性生成
在项目根目录或者IDEA terminal中输入:
flutter packages pub run build_runner build
- 自动方式:持续生成
在项目根目录或者IDEA terminal中输入:
flutter packages pub run build_runner watch
它会监视我们项目中文件的变化,并在需要时自动构建必要的文件。源代码生成器创建一个名为user.g.dart的文件,它具有所有必需的序列化逻辑。
如果需要,自定义命名策略也很容易。例如,如果我们正在使用的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;