Flutter数据序列化插件dson的使用
Flutter数据序列化插件dson的使用
DSON是一个将Dart对象转换为它们的JSON表示形式的库。
特点
- DSON使用
serializable
和built_mirrors
库来替代Dartson使用的自定义转换器。 - DSON支持序列化循环引用,并通过
expand
参数允许用户指定要序列化的对象图深度。 - DSON提供了两种方式排除属性:
- 使用
@ignore
注解每个属性。 - 使用
exclude
映射作为toJson
方法的参数。
- 使用
安装和配置
- 创建一个新的Dart项目。
- 在
pubspec.yaml
文件中添加依赖项:
dependencies:
#...
dson: any # 替换为最新版本
#...
dev_dependencies:
#...
build_runner: any
build_web_compilers: any
#...
- 编辑
bin/main.dart
或web/main.dart
文件并添加以下代码:
library example.object_to_json; // 这一行是为了生成器
import 'package:dson/dson.dart';
part 'object_to_json.g.dart'; // 这一行是为了生成器
[@serializable](/user/serializable)
class Person extends SerializableMap with _$PersonSerializable {
int? id;
String? firstName;
var lastName; // 这是一个动态属性,可以是String, int, double, num, date或其他类型
double? height;
DateTime? dateOfBirth;
@SerializedName("renamed")
String? otherName;
@ignore
String? notVisible;
// 私有成员永远不会被序列化
String? _private = "name";
String? get doGetter => _private;
}
void main() {
_initMirrors();
Person object = Person()
..id = 1
..firstName = "Jhon"
..lastName = "Doe"
..height = 1.8
..dateOfBirth = DateTime(1988, 4, 1, 6, 31)
..otherName = "Juan"
..notVisible = "hallo";
String jsonString = toJson(object);
print(jsonString);
// 将打印: '{"id":1,"firstName":"Jhon","lastName":"Doe","height":1.8,"dateOfBirth":"1988-04-01T06:31:00.000","renamed":"Juan","doGetter":"name"}'
}
- 运行以下命令之一:
dart run build_runner build
dart run build_runner watch
dart run build_runner serve
将对象转换为JSON字符串
要将对象转换为JSON字符串,只需使用toJson
函数,并传递object
给该函数作为参数:
library example.object_to_json; // 这一行是为了生成器
import 'package:dson/dson.dart';
part 'object_to_json.g.dart'; // 这一行是为了生成器
[@serializable](/user/serializable)
class Person extends SerializableMap with _$PersonSerializable {
int? id;
String? firstName;
var lastName; // 这是一个动态属性,可以是String, int, double, num, date或其他类型
double? height;
DateTime? dateOfBirth;
@SerializedName("renamed")
String? otherName;
@ignore
String? notVisible;
// 私有成员永远不会被序列化
String? _private = "name";
String? get doGetter => _private;
}
void main() {
_initMirrors();
Person object = Person()
..id = 1
..firstName = "Jhon"
..lastName = "Doe"
..height = 1.8
..dateOfBirth = DateTime(1988, 4, 1, 6, 31)
..otherName = "Juan"
..notVisible = "hallo";
String jsonString = toJson(object);
print(jsonString);
// 将打印: '{"id":1,"firstName":"Jhon","lastName":"Doe","height":1.8,"dateOfBirth":"1988-04-01T06:31:00.000","renamed":"Juan","doGetter":"name"}'
}
将对象转换为Map
要将对象转换为Map,只需使用toMap
函数,并传递object
给该函数作为参数:
library example.object_to_map; // 这一行是为了生成器
import 'package:dson/dson.dart';
part 'object_to_map.g.dart'; // 这一行是为了生成器
[@serializable](/user/serializable)
class Person extends SerializableMap with _$PersonSerializable {
int? id;
String? firstName;
var lastName; // 这是一个动态属性,可以是String, int, double, num, date或其他类型
double? height;
DateTime? dateOfBirth;
@SerializedName("renamed")
String? otherName;
@ignore
String? notVisible;
// 私有成员永远不会被序列化
String? _private = "name";
String? get doGetter => _private;
}
void main() {
_initMirrors();
Person object = Person()
..id = 1
..firstName = "Jhon"
..lastName = "Doe"
..height = 1.8
..dateOfBirth = DateTime(1988, 4, 1, 6, 31)
..otherName = "Juan"
..notVisible = "hallo";
Map map = toMap(object);
print(map);
// 将打印: '{id:1, firstName: Jhon, lastName: Doe, height: 1.8, dateOfBirth: 1988-04-01T06:31:00.000, renamed: Juan, doGetter: name}'
}
序列化循环引用的对象
要序列化包含循环引用的对象,需要使用@cyclical
注解。如果存在此注解且未设置expand
变量,则非原始对象将不会被解析,仅ID(或哈希表,如果对象不包含ID)将存在。让我们看下一个例子:
library example.serialize_cyclical; // 这一行是为了生成器
import 'package:dson/dson.dart';
part 'serialize_cyclical.g.dart'; // 这一行是为了生成器
[@serializable](/user/serializable)
@cyclical
class Employee extends SerializableMap with _$EmployeeSerializable {
@uId int? key;
String? firstName;
String? lastName;
Address? address;
Employee? manager;
}
[@serializable](/user/serializable)
@cyclical
class Address extends SerializableMap with _$AddressSerializable {
@uId int? key;
String? street;
String? city;
String? country;
String? postalCode;
Employee? owner;
}
void main() {
_initMirrors();
var manager = Employee()
..key = 1
..firstName = 'Jhon'
..lastName = 'Doe';
manager.address = Address()
..key = 1
..street = 'some street'
..city = 'Miami'
..country = 'USA'
..owner = manager;
var employee = Employee()
..key = 2
..firstName = 'Luis'
..lastName = 'Vargas'
..manager = manager;
employee.address = Address()
..key = 2
..street = 'some street'
..city = 'Miami'
..country = 'USA'
..owner = employee;
print(toJson(employee)); // 将打印: '{"id":2,"firstName":"Luis","lastName":"Vargas","address":{"id":2},"manager":{"id":1}}'
print(toJson(employee.address)); // 将打印: '{"id":2,"street":"some street","city":"Miami","country":"USA","owner":{"id":2}}'
// depth是一个可选参数,可以是一个字符串列表或Map<String, Map>
print(toJson(employee, expand: ['address']));
/* 将打印:
'{"id":2,"firstName":"Luis","lastName":"Vargas",'
'"address":{"id":2,"street":"some street","city":"Miami","country":"USA","owner":{"id":2}},'
'"manager":{"id":1}}'
*/
print(toJson(employee, expand: [{'manager': ['address']}, 'address']));
/* 将打印:
'{"id":2,"firstName":"Luis","lastName":"Vargas",'
'"address":{"id":2,"street":"some street","city":"Miami","country":"USA",'
'"owner":{"id":2}},'
'"manager":{"id":1,"firstName":"Jhon","lastName":"Doe",'
'"address":{"id":1,"street":"some street","city":"Miami","country":"USA","owner":{"id":1}}}}');
*/
}
排除属性以避免序列化
要排除属性以避免序列化,有两种选择:
- 使用
@ignore
注解属性以忽略它。然而这种方法过于全局化。 - 向
toJson
函数添加exclude
参数。这样我们只在该次序列化中排除那些属性。
library example.exclude_attributes; // 这一行是为了生成器
import 'package:dson/dson.dart';
part 'exclude_attributes.g.dart'; // 这一行是为了生成器
[@serializable](/user/serializable)
@cyclical
class Student extends SerializableMap with _$StudentSerializable {
int? id;
String? name;
List<Course>? courses;
}
[@serializable](/user/serializable)
@cyclical
class Course extends SerializableMap with _$CourseSerializable {
int? id;
DateTime? beginDate;
List<Student>? students;
}
void main() {
_initMirrors();
var student1 = Student()
..id = 1
..name = 'student1',
student2 = Student()
..id = 2
..name = 'student2',
student3 = Student()
..id = 3
..name = 'student3',
course1 = Course()
..id = 1
..beginDate = DateTime.utc(2015, 1, 1)
..students = [student1, student2],
course2 = Course()
..id = 2
..beginDate = DateTime.utc(2015, 1, 2)
..students = [student2, student3],
course3 = Course()
..id = 3
..beginDate = DateTime.utc(2015, 1, 3)
..students = [student1, student3];
student1.courses = [course1, course3];
student2.courses = [course1, course2];
student3.courses = [course2, course3];
var students = [student1, student2, student3];
print(toJson(students));
/*
将打印:
'['
'{"id":1,"name":"student1","courses":[{"id":1},{"id":3}]},'
'{"id":2,"name":"student2","courses":[{"id":1},{"id":2}]},'
'{"id":3,"name":"student3","courses":[{"id":2},{"id":3}]}'
']'
*/
print(toJson(student1)); // 将打印: '{"id":1,"name":"student1","courses":[{"id":1},{"id":3}]}'
print(toJson(student1, expand: 'courses', exclude: 'name'));
/* 将打印:
'{'
'"id":1,'
'"courses":['
'{"id":1,"beginDate":"2015-01-01T00:00:00.000Z","students":[{"id":1},{"id":2}]},'
'{"id":3,"beginDate":"2015-01-03T00:00:00.000Z","students":[{"id":1},{"id":3}]}'
']'
'}');
*/
print(toJson(student1.courses, exclude: 'beginDate'));
/* 将打印:
'['
'{"id":1,"students":[{"id":1},{"id":2}]},'
'{"id":3,"students":[{"id":1},{"id":3}]}'
']');
*/
print(toJson(student2.courses, expand: 'students', exclude: {'students': 'name'}));
/* 将打印:
'['
'{"id":1,"beginDate":"2015-01-01T00:00:00.000Z","students":['
'{"id":1,"courses":[{"id":1},{"id":3}]},'
'{"id":2,"courses":[{"id":1},{"id":2}]}'
']},'
'{"id":2,"beginDate":"2015-01-02T00:00:00.000Z","students":['
'{"id":2,"courses":[{"id":1},{"id":2}]},'
'{"id":3,"courses":[{"id":2},{"id":3}]}'
']}'
']'
*/
print(toJson(student2.courses, expand: 'students', exclude: ['beginDate', {'students': 'name'}]));
/* 将打印:
'['
'{"id":1,"students":['
'{"id":1,"courses":[{"id":1},{"id":3}]},'
'{"id":2,"courses":[{"id":1},{"id":2}]}'
']},'
'{"id":2,"students":['
'{"id":2,"name":"student2","courses":[{"id":1},{"id":2}]},'
'{"id":3,"name":"student3","courses":[{"id":2},{"id":3}]}'
']}'
']'
*/
}
将JSON字符串转换为对象
要将JSON字符串转换为对象,只需使用fromJson
和fromJsonList
函数,并传递要反序列化的JSON字符串和对象类型作为参数:
library example.json_to_object; // 这一行是为了生成器
import 'package:dson/dson.dart';
part 'json_to_object.g.dart'; // 这一行是为了生成器
[@serializable](/user/serializable)
class EntityClass extends SerializableMap with _$EntityClassSerializable {
String? name;
String? _setted;
@SerializedName("renamed")
bool? otherName;
@ignore
String? notVisible;
List<EntityClass>? children;
set setted(String? s) => _setted = s;
String? get setted => _setted;
}
void main() {
_initMirrors();
EntityClass object = fromJson('{"name":"test","renamed":true,"notVisible":"it is", "setted": "awesome"}', EntityClass);
print(object.name); // > test
print(object.otherName); // > blub
print(object.notVisible); // > it is
print(object.setted); // > awesome
// 反序列化一个项目的列表使用[fromJsonList]
List<EntityClass> list = fromJson(
'[{"name":"test", "children": [{"name":"child1"},{"name":"child2"}]},{"name":"test2"}]',
[() => List<EntityClass>.empty(growable: true), EntityClass]);
print(list.length); // > 2
print(list[0].name); // > test
print(list[0].children?[0].name); // > child1
}
将Map
和List<Map>
转换为Dart对象
一些框架如Angular.dart会自带HTTP服务,这些服务会将HTTP响应转换为使用JSON.encode
的Map。为了使用这些编码的Map或List,可以使用fromMap
函数。
library example.map_to_object; // 这一行是为了生成器
import 'package:dson/dson.dart';
part 'map_to_object.g.dart'; // 这一行是为了生成器
[@serializable](/user/serializable)
class EntityClass extends SerializableMap with _$EntityClassSerializable {
String? name;
String? _setted;
@SerializedName("renamed")
bool? otherName;
@ignore
String? notVisible;
List<EntityClass>? children;
set setted(String? s) => _setted = s;
String? get setted => _setted;
}
void main() {
_initMirrors();
EntityClass object = fromMap({
"name": "test",
"renamed": true,
"notVisible": "it is",
"setted": "awesome"
}, EntityClass);
print(object.name); // > test
print(object.otherName); // > blub
print(object.notVisible); // > it is
print(object.setted); // > awesome
// 反序列化一个项目的列表使用[fromJsonList]
List<EntityClass> list = fromMap([
{"name": "test",
"children": [
{"name": "child1"},
{"name": "child2"}
]
},
{"name": "test2"}
], [() => List<EntityClass>.empty(growable: true), EntityClass]);
print(list.length); // > 2
print(list[0].name); // > test
print(list[0].children?[0].name); // > child1
}
扩展可序列化对象
要扩展即将序列化的对象,你需要添加注释:
// ignore: mixin_inherits_from_not_object
这是为了让分析器忽略继承自非混合类的错误。例如:
library extend_serializables;
import 'package:dson/dson.dart';
part 'extend_serializables.g.dart';
[@serializable](/user/serializable)
class Person extends SerializableMap with _$PersonSerializable {
int? id;
String? firstName;
String? lastName;
DateTime? dateOfBirth;
}
[@serializable](/user/serializable)
// ignore: mixin_inherits_from_not_object
class Employee extends Person with _$EmployeeSerializable {
double? salary;
}
[@serializable](/user/serializable)
// ignore: mixin_inherits_from_not_object
class Manager extends Employee with _$ManagerSerializable {
List<Employee>? subordinates;
}
main() {
_initMirrors();
var person = Person()
..id = 1
..firstName = 'Jhon'
..lastName = 'Doe'
..dateOfBirth = DateTime.now();
var personJson = toJson(person);
print('personJson: $personJson');
var employee = Employee()
..id = 1
..firstName = 'Employee'
..lastName = 'Doe'
..dateOfBirth = DateTime.now()
..salary = 1000.0;
var employeeJson = toJson(employee);
print('employeeJson: $employeeJson');
var manager = Manager()
..id = 1
..firstName = 'Manager'
..lastName = 'Doe'
..dateOfBirth = DateTime.now()
..salary = 2000.0
..subordinates = [employee];
var managerJson = toJson(manager);
print('managerJson: $managerJson');
}
序列化/反序列化不可变对象
要使不可变类能够序列化/反序列化,你只需要声明一个只包含final参数的构造函数。例如:
library example.serialize_final_objects;
import 'package:dson/dson.dart';
part 'immutable_objects.g.dart';
[@serializable](/user/serializable)
class Person extends SerializableMap with _$PersonSerializable {
final int id;
final String? name;
Person({this.id = 0, this.name});
}
main() {
_initMirrors();
var p1 = Person(id: 1, name: 'Jhon Doe');
var p1Json = toJson(p1);
print('p1Json: $p1Json');
var p1FromJson = fromJson(p1Json, Person);
print('p1FromJson: (id: ${p1FromJson.id}, name: ${p1FromJson.name})');
}
注意:确保字段和构造函数参数的名称匹配。如果不匹配,则反序列化后的对象将包含null值。
序列化/反序列化泛型对象
序列化泛型对象非常简单,你只需要调用toJson
函数:
library example.generics;
import 'package:dson/dson.dart';
part 'generics.g.dart';
[@serializable](/user/serializable)
class Page<T> extends SerializableMap with _$PageSerializable<T> {
int? size;
int? total;
int? number;
List<T>? items;
}
[@serializable](/user/serializable)
class Person extends SerializableMap with _$PersonSerializable {
int? id;
String? name;
}
main() {
_initMirrors();
var p = Person()
..id = 1
..name = 'person 1';
var page = Page<Person>()
..size = 1
..number = 1
..total = 100
..items = [p];
// tag::serialize[]
var jsonStr = toJson(page);
// end::serialize[]
print('jsonStr: $jsonStr');
// tag::deserialize[]
Page<Person> page2 = fromJson(jsonStr, [() => Page<Person>(), {'items': [() => List<Person>.empty(growable: true), Person]}]);
// end::deserialize[]
print('page2.size: ${page2.size}');
print('page2.number: ${page2.number}');
print('page2.total: ${page2.total}');
print('page2.items[0].id: ${page2.items?[0].id}');
print('page2.items[0].name: ${page2.items?[0].name}');
}
反序列化则更为复杂。你需要指定一个工厂和类型的列表,从顶层类开始。在同一工厂列表中,你还需要指定一个通用属性的工厂映射。例如:
library example.generics;
import 'package:dson/dson.dart';
part 'generics.g.dart';
[@serializable](/user/serializable)
class Page<T> extends SerializableMap with _$PageSerializable<T> {
int? size;
int? total;
int? number;
List<T>? items;
}
[@serializable](/user/serializable)
class Person extends SerializableMap with _$PersonSerializable {
int? id;
String? name;
}
main() {
_initMirrors();
var p = Person()
..id = 1
..name = 'person 1';
var page = Page<Person>()
..size = 1
..number = 1
..total = 100
..items = [p];
// tag::serialize[]
var jsonStr = toJson(page);
// end::serialize[]
print('jsonStr: $jsonStr');
// tag::deserialize[]
Page<Person> page2 = fromJson(jsonStr, [() => Page<Person>(), {'items': [() => List<Person>.empty(growable: true), Person]}]);
// end::deserialize[]
print('page2.size: ${page2.size}');
print('page2.number: ${page2.number}');
print('page2.total: ${page2.total}');
print('page2.items[0].id: ${page2.items?[0].id}');
print('page2.items[0].name: ${page2.items?[0].name}');
}
序列化/反序列化扩展的泛型对象
扩展的泛型也可以由这个库处理。例如,你可以使用以下代码:
library extend_generics;
import 'package:dson/dson.dart';
part 'extend_generics.g.dart';
abstract class IManager<T> {
List<Employee<T>>? subordinates;
}
[@serializable](/user/serializable)
class Person<T> extends SerializableMap with _$PersonSerializable<T> {
int? id;
String? firstName;
T? lastName;
DateTime? dateOfBirth;
}
[@serializable](/user/serializable)
// ignore: mixin_inherits_from_not_object
class Employee<T> extends Person<T> with _$EmployeeSerializable<T> {
double? salary;
}
[@serializable](/user/serializable)
// ignore: mixin_inherits_from_not_object
class Manager<T> extends Employee<T> with _$ManagerSerializable<T> implements IManager<T> {
List<Employee<T>>? subordinates;
}
main() {
_initMirrors();
var person = Person<String>()
..id = 1
..firstName = 'Jhon'
..lastName = 'Doe'
..dateOfBirth = DateTime.now();
var personJson = toJson(person);
print('personJson: $personJson');
Person<String> person2 = fromJson(personJson, [() => Person<String>(), {'lastName': String}]);
print('\nPerson From Json:');
print('person2.firstName: ${person2.firstName}');
print('person2.lastName: ${person2.lastName}\n');
var employee = Employee<String>()
..id = 1
..firstName = 'Employee'
..lastName = 'Doe'
..dateOfBirth = DateTime.now()
..salary = 1000.0;
print(employee.runtimeType);
var employeeJson = toJson(employee);
print('employeeJson: $employeeJson');
Employee<String> employee2 = fromJson(employeeJson, [() => Employee<String>(), {'lastName': String}]);
print('\nEmployee From Json:');
print('employee2.firstName: ${employee2.firstName}');
print('employee2.lastName: ${employee2.lastName}');
print('employee2.salary: ${employee2.salary}\n');
var manager = Manager<String>()
..id = 1
..firstName = 'Manager'
..lastName = 'Doe'
..dateOfBirth = DateTime.now()
..salary = 2000.0
..subordinates = [employee];
var managerJson = toJson(manager);
print('managerJson: $managerJson');
Manager<String> manager2 = fromJson(managerJson, [() => Manager<String>(), {'lastName': String}]);
print('\nManager From Json:');
print('manager2.firstName: ${manager2.firstName}');
print('manager2.lastName: ${manager2.lastName}');
print('manager2.salary: ${manager2.salary}');
print('manager2.subordinates: ${manager2.subordinates}');
}
更多关于Flutter数据序列化插件dson的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter数据序列化插件dson的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter项目中使用dson
插件进行数据序列化和反序列化的代码示例。dson
是一个强大的Flutter插件,用于处理JSON数据的编码和解码。
首先,你需要在你的pubspec.yaml
文件中添加dson
依赖:
dependencies:
flutter:
sdk: flutter
dson: ^x.y.z # 替换为最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,让我们看一个具体的代码示例:
- 定义数据模型:
import 'package:dson/dson.dart';
@DSonSerializable
class User {
String name;
int age;
String email;
User() {}
// 你可以使用生成器生成这个构造函数
// 运行 `flutter pub run build_runner build`
// 然后 `User.fromJson(Map<String, dynamic> json)` 和 `Map<String, dynamic> toJson()` 会自动生成
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}
注意:为了使@DSonSerializable
注解工作,你需要使用JSON生成器来生成fromJson
和toJson
方法。你可以在项目根目录运行以下命令来生成这些方法:
flutter pub run build_runner build
- 使用
dson
进行序列化和反序列化:
import 'package:flutter/material.dart';
import 'dart:convert';
import 'user_model.dart'; // 假设上面的User类在这个文件中
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Dson Example'),
),
body: Center(
child: DsonExample(),
),
),
);
}
}
class DsonExample extends StatefulWidget {
@override
_DsonExampleState createState() => _DsonExampleState();
}
class _DsonExampleState extends State<DsonExample> {
User user;
@override
void initState() {
super.initState();
// 创建一个User对象
user = User()
..name = 'John Doe'
..age = 30
..email = 'john.doe@example.com';
// 将User对象序列化为JSON字符串
String jsonString = jsonEncode(user.toJson());
print('Serialized JSON: $jsonString');
// 将JSON字符串反序列化为User对象
User deserializedUser = User.fromJson(jsonDecode(jsonString));
print('Deserialized User: ${deserializedUser.name}, ${deserializedUser.age}, ${deserializedUser.email}');
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Check the console for serialized and deserialized output.'),
],
);
}
}
在这个示例中,我们定义了一个User
类,并使用@DSonSerializable
注解标记它。然后,我们创建了一个User
对象,并将其序列化为JSON字符串,再将其反序列化为User
对象。
请注意,为了使fromJson
和toJson
方法自动生成,你需要使用build_runner
工具。确保你已经添加了build_runner
到你的dev_dependencies
中:
dev_dependencies:
build_runner: ^x.y.z # 替换为最新版本号
然后运行flutter pub get
和flutter pub run build_runner build
来生成这些方法。
这就是如何在Flutter项目中使用dson
进行数据序列化和反序列化的基本步骤。希望这对你有所帮助!