Flutter数据序列化插件jsonable的使用
Flutter数据序列化插件jsonable的使用
Jsonable 是一个库,它提供了一种简单的方式来管理 Dart 类的 fromJson
和 toJson
方法,允许在 Dart 和 JSON 之间进行转换。Jsonable 的主要目标和哲学是移除生成的代码,使得任何对象都可以转换为 JSON。
在 Jsonable 的第一个版本中,使用了反射,但这不支持 Dart 的 AOT 编译器。因此,Jsonable 不使用反射或生成的代码。
如何使用?
Jsonable 提供了一个混入类 mixin Jsonable
,在这个混入类中管理了 JSON 方案。只需要通过扩展我们的类来使用这个混入类,该类就会获得必要的方法。但是,如果我们不指定 JSON 的成员,使用 toJson
或 toMap
将会返回一个空的 Map/字符串({})。
让我们看一个例子:
import "package:jsonable/jsonable.dart";
class Person with Jsonable {
JString name;
JString surname;
Person() {
this.name = this.jString("name");
this.surname = this.jString("surname");
}
}
void main() {
var p = Person()..fromMap({
"name": "Nico",
"surname": "Spina"
});
print(p.toJson());
// 输出: {"name":"Nico","surname":"Spina"}
}
在这个例子中,类成员(JString name
和 JString surname
)的作用是保持对 JType
的引用。如果你不需要这些引用,可以定义一个更紧凑的类:
import "package:jsonable/jsonable.dart";
class Person with Jsonable {
Person() {
jString("name");
jString("surname");
}
}
void main() {
var p = Person()..fromMap({
"name": "Nico",
"surname": "Spina"
});
print(p.toJson());
// 输出: {"name":"Nico","surname":"Spina"}
}
Jsonable 实现了不同的类型来表示整个 JSON 结构:
JString
JNum
JBool
JClass<E extends Jsonable>
JList<E>
JDynamic
JMap
Jsonable 记录这些类型,并基于这些类型进行序列化和反序列化。
Jsonable 提供的方法
JClass<E>
JClass<E> jClass<E extends Jsonable>(keyname, JsonableConstructor constructor, {E initialValue})
返回一个 JClass
,它是 <JType<Jsonable>>
的泛型。此外,它需要一个构造函数,这是一个简单的函数,返回该类型的实例。注意,如果 initialValue
为空,它将立即实例化。
JList<E>
JList<E> jList<E>(dynamic keyname, {List<E> initialValue, JsonableConstructor constructor})
JList
表示一个可以包含任何值的列表。你可以迭代 JList
,并且不需要通过 .value
访问值。在这种类型中,构造函数参数成为必需项,如果你使用的是 Jsonable
作为泛型,不允许其他数据类型:bool
, string
, num
, int
, double
, map
, list
。
JString
JString jString(dynamic keyname, {String initialValue})
返回一个 <JType<String>>
,然后管理 String
类型的方案。在 fromJson
中,只有当值是 String
时才会分配值,在 toJson
中,它会分配一个 String
。你只能通过 .value
分配 String
值。
JBool
JBool jBool(dynamic keyname, {bool initialValue})
返回一个 <JType<bool>>
,然后管理 bool
类型的方案。在 fromJson
中,只有当值是 bool
时才会分配值,在 toJson
中,它会分配一个 bool
。你只能通过 .value
分配 bool
值。
JNum
JNum jNum(dynamic keyname, {num initialValue})
返回一个 <JType<num>>
,然后管理 num
类型的方案。在 fromJson
中,只有当值是 num
时才会分配值,在 toJson
中,它会分配一个 num
。你只能通过 .value
分配 num
值。
JMap
JMap jMap(dynamic keyname, {Map initialValue})
返回一个 <JType<Map<E,R>>>
,然后管理 Map<E,R>
类型的方案。在 fromJson
中,只有当值是 Map<E,R>
时才会分配值,在 toJson
中,它会分配一个 Map<E,R>
。你只能通过 .value
分配 Map<E,R>
值。
JDynamic
JDynamic jDynamic(dynamic keyname, {dynamic initialValue})
返回一个 <JType<dynamic>>
,然后管理 dynamic
类型的方案。在 fromJson
中,只有当值是 dynamic
时才会分配值,在 toJson
中,它会分配一个 dynamic
。你只能通过 .value
分配 dynamic
值。
验证
从 Jsonable 0.1.0
版本开始,引入了 JSON 模式验证的支持。
验证是通过“规则”完成的,这些规则由 Rules
类提供。
规则应用于单个字段并验证单个字段。每个字段,即每个 JType
都有 validate()
方法,该方法返回一个元素列表,这些元素是异常 RuleException
。每个规则都有自己的异常,并且所有这些异常都继承自 RuleException
。以下是一个应用规则的小例子:
import 'package:jsonable/jsonable.dart';
class Person with Jsonable {
JString name;
JString surname;
JNum years;
Person() {
name = this.jString("name", rules: [
Rules.max(12),
Rules.min(4),
]);
surname = this.jString("surname", rules: [
Rules.min(4),
Rules.max(12),
]);
years = this.jNum("years", rules: [
Rules.min(18, message: "我的个人错误消息!"),
Rules.max(99),
]);
}
}
Jsonable
混入还提供了一个 validated
方法,它将返回 <Map<String, List<RuleException>>>
,其中键(String)是字段名,而值是单个值的异常列表。混入中的 validate()
方法调用了其内部每个元素的 validates
方法。
自定义规则
创建自定义规则可能非常有用,以便覆盖规则不支持的行为。
要创建自定义规则,可以使用 Rules.customRule()
方法。
这个方法接受两个必要且强制的参数以正确创建你的规则。例如:
import 'package:jsonable/jsonable.dart';
var myPersonalRule = Rules.customRule((JType value) {
if (value is JString) {
if (value.getString() != "Nico") {
return true;
}
}
return false;
}, (JType value) => RuleException("${value.keyname} 哦,不!!"));
class Person with Jsonable {
JString name;
Person() {
this.name = this.jString("name", rules: [myPersonalRule]);
}
}
更多关于Flutter数据序列化插件jsonable的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter数据序列化插件jsonable的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter中使用jsonable
插件进行数据序列化和反序列化的示例代码。需要注意的是,jsonable
插件并不是Flutter官方或广泛认可的插件,因此这个示例假设jsonable
插件的API类似于其他常见的JSON序列化/反序列化库。如果实际插件API有所不同,请根据文档进行调整。
首先,确保你的pubspec.yaml
文件中已经添加了jsonable
插件的依赖(假设该插件存在并且名为jsonable
,实际上你可能需要查找真实的插件名和依赖地址):
dependencies:
flutter:
sdk: flutter
jsonable: ^x.y.z # 替换为实际的版本号
然后,运行flutter pub get
来安装依赖。
以下是一个简单的示例,展示如何使用jsonable
插件将一个Dart对象序列化为JSON字符串,以及将JSON字符串反序列化为Dart对象。
Dart对象定义
假设我们有一个简单的用户对象:
class User {
String name;
int age;
User({required this.name, required this.age});
// 用于jsonable插件的fromMap和toMap方法(假设插件需要这些)
factory User.fromJson(Map<String, dynamic> json) => User(
name: json['name'] as String,
age: json['age'] as int,
);
Map<String, dynamic> toJson() => {
'name': name,
'age': age,
};
}
使用jsonable进行序列化和反序列化
假设jsonable
插件提供了类似encode
和decode
的方法,以下是如何使用它们:
import 'package:jsonable/jsonable.dart'; // 假设这是jsonable的导入路径
import 'dart:convert'; // 导入dart的convert库作为对比
void main() {
// 创建一个User对象
User user = User(name: 'Alice', age: 30);
// 使用jsonable将User对象序列化为JSON字符串
// 注意:这里的jsonableEncode是一个假设的方法名,实际使用时请替换为真实的方法名
String jsonString = jsonableEncode(user);
print('Serialized JSON: $jsonString');
// 使用dart的JsonEncoder作为对比
String dartJsonString = jsonEncode(user.toJson());
print('Dart Serialized JSON: $dartJsonString');
// 假设jsonString是从某个地方接收到的JSON字符串
String receivedJsonString = jsonString;
// 使用jsonable将JSON字符串反序列化为User对象
// 注意:这里的jsonableDecode是一个假设的方法名,实际使用时请替换为真实的方法名
User deserializedUser = jsonableDecode(receivedJsonString, User.fromJson);
print('Deserialized User: ${deserializedUser.name}, ${deserializedUser.age}');
// 使用dart的JsonDecoder作为对比
Map<String, dynamic> dartJsonMap = jsonDecode(dartJsonString);
User dartDeserializedUser = User.fromJson(dartJsonMap);
print('Dart Deserialized User: ${dartDeserializedUser.name}, ${dartDeserializedUser.age}');
}
注意
- 实际方法名:
jsonableEncode
和jsonableDecode
是假设的方法名。你需要查阅jsonable
插件的实际文档来确定正确的方法名。 - 工厂构造函数:
User.fromJson
是一个工厂构造函数,它用于从JSON数据创建User
对象。 - toMap方法:
toJson
方法用于将User
对象转换为JSON映射。
如果jsonable
插件实际上并不提供类似的方法,你可能需要查阅其他流行的JSON序列化库,如json_serialization
(需要手动编写序列化逻辑)或使用Flutter社区更广泛接受的插件,如json_annotation
与build_runner
结合使用。