Flutter数据序列化插件jsonable的使用

发布于 1周前 作者 eggper 来自 Flutter

Flutter数据序列化插件jsonable的使用

Jsonable 是一个库,它提供了一种简单的方式来管理 Dart 类的 fromJsontoJson 方法,允许在 Dart 和 JSON 之间进行转换。Jsonable 的主要目标和哲学是移除生成的代码,使得任何对象都可以转换为 JSON。

在 Jsonable 的第一个版本中,使用了反射,但这不支持 Dart 的 AOT 编译器。因此,Jsonable 不使用反射或生成的代码。

如何使用?

Jsonable 提供了一个混入类 mixin Jsonable,在这个混入类中管理了 JSON 方案。只需要通过扩展我们的类来使用这个混入类,该类就会获得必要的方法。但是,如果我们不指定 JSON 的成员,使用 toJsontoMap 将会返回一个空的 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 nameJString 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

1 回复

更多关于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插件提供了类似encodedecode的方法,以下是如何使用它们:

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}');
}

注意

  1. 实际方法名jsonableEncodejsonableDecode是假设的方法名。你需要查阅jsonable插件的实际文档来确定正确的方法名。
  2. 工厂构造函数User.fromJson是一个工厂构造函数,它用于从JSON数据创建User对象。
  3. toMap方法toJson方法用于将User对象转换为JSON映射。

如果jsonable插件实际上并不提供类似的方法,你可能需要查阅其他流行的JSON序列化库,如json_serialization(需要手动编写序列化逻辑)或使用Flutter社区更广泛接受的插件,如json_annotationbuild_runner结合使用。

回到顶部