Flutter对象序列化插件object_serializer的使用

Flutter对象序列化插件object_serializer的使用

object_serializer 是一个用于将数据以多种方式(如JSON、对象等)进行序列化的插件。版本为0.4.0。

目前有两个类型的序列器可用:

  • JSON序列器
  • 对象序列器

JSON序列器

JSON序列器 是一个将数据序列化为标准JSON格式的序列器。它支持可以转换为简单数据类型的数据类型(例如 BigIntDateTimeDurationUri 等)。其工作原理很简单,你需要自己选择数据的序列化和反序列化方法,即你完全控制这一过程。

示例

classes:
  Foo:
    fields:
      bar: Bar
  Bar:
    fields:
      baz: Baz
  Baz:
    fields:
      date1:
        type: DateTime
        deserialize: |-
          _Serializer.deserialize<DateTime>
        serialize:
          _Serializer.serialize<DateTime>
      date2:
        type: DateTime?
        deserializer: _Serializer
        serializer: _Serializer

  Response:
    typeParameters: <T1, T2, T3>
    fields:
      data1:
        type: T1
        deserialize: |-
          _Serializer.deserialize<T>
        serialize:
          _Serializer.serialize<T>
      data2:
        type: T2?
        deserializer: _Serializer
        serializer: _Serializer
      data3:
        type: T3
        serialization: _Serializer

serializers:
  _Serializer:
    types:
      Bar:
      Baz:
      Foo:
      DateTime:
        deserialize: |-
          result = DateTime.fromMicrosecondsSinceEpoch(int.parse(value as String));
        serialize: |-
          result = (value as DateTime).microsecondsSinceEpoch.toString();

接下来,让我们尝试生成代码。我们可以通过项目构建过程来完成这一操作。

我们将这个文件命名为 example/example_models.json.yaml

pubspec.yaml 文件中添加依赖项:

dev_dependencies:
  build_runner: any
  object_serializer: ^0.3.6

然后启动构建过程:

dart run build_runner build

经过 build_runner 的操作后,将生成 example/example_models.json.dart 文件。

class Foo {
  Foo({required this.bar});

  factory Foo.fromJson(Map json) {
    return Foo(
      bar: Bar.fromJson(json['bar'] as Map),
    );
  }

  final Bar bar;

  static List<Foo> fromJsonList(List json) {
    return json.map((e) => Foo.fromJson(e as Map)).toList();
  }

  Map<String, dynamic> toJson() {
    return {
      'bar': bar.toJson(),
    };
  }

  static List<Map<String, dynamic>> toJsonList(List<Foo> list) {
    return list.map((e) => e.toJson()).toList();
  }
}

class Bar {
  Bar({required this.baz});

  factory Bar.fromJson(Map json) {
    return Bar(
      baz: Baz.fromJson(json['baz'] as Map),
    );
  }

  final Baz baz;

  static List<Bar> fromJsonList(List json) {
    return json.map((e) => Bar.fromJson(e as Map)).toList();
  }

  Map<String, dynamic> toJson() {
    return {
      'baz': baz.toJson(),
    };
  }

  static List<Map<String, dynamic>> toJsonList(List<Bar> list) {
    return list.map((e) => e.toJson()).toList();
  }
}

class Baz {
  Baz({required this.date});

  factory Baz.fromJson(Map json) {
    return Baz(
      date: _DateTimeSerializer.deserialize(json['date']),
    );
  }

  final DateTime date;

  static List<Baz> fromJsonList(List json) {
    return json.map((e) => Baz.fromJson(e as Map)).toList();
  }

  Map<String, dynamic> toJson() {
    return {
      'date': _DateTimeSerializer.serialize(date),
    };
  }

  static List<Map<String, dynamic>> toJsonList(List<Baz> list) {
    return list.map((e) => e.toJson()).toList();
  }
}

class _DateTimeSerializer {
  static DateTime deserialize(Object? value) {
    final json = value as String;
    return DateTime.fromMicrosecondsSinceEpoch(int.parse(json));
  }

  static Object? serialize(DateTime value) {
    return value.microsecondsSinceEpoch.toString();
  }
}

第二种方法是使用生成器来实现。你可以在这里找到生成器脚本的示例:

import 'package:object_serializer/object_serializer.dart';
import 'package:object_serializer/serialize.dart';
import 'package:test/test.dart';
import 'package:tuple/tuple.dart';

Future<void> main() async {
  test(
    'Example',
    () async {
      final _ComplexType map = {
        Uri.parse('package:animals'): [
          Tuple2(BigInt.parse('1'), Tuple2(1, A('Hello'))),
          Tuple2(BigInt.parse('2'), Tuple2(1, A('Hello'))),
        ],
        Uri.parse('package:zoo'): [
          Tuple2(BigInt.parse('1'), Tuple2(1, B('Goodbye', 41))),
          Tuple2(BigInt.parse('2'), Tuple2(2, null)),
          Tuple2(BigInt.parse('1'), Tuple2(1, A('Hello'))),
        ],
      };

      final stream = serializeMap(map, _collection);

      //
      final port = ReceivePort();
      final isolate =
          await Isolate.spawn<List>(compute, [port.sendPort, stream]);
      final stream2 = await port.first as List;
      isolate.kill(priority: Isolate.immediate);

      //
      final _ComplexType result = deserializeMap(stream2, _collection);
      expect(result, map);
    },
  );
}

final _collection = ObjectSerializerCollection()
  ..addSerializer(ListSerializer<Tuple2<BigInt, Tuple2<int, Base?>>>())
  ..addSerializer(_ASerializer())
  ..addSerializer(_BSerializer())
  ..addSerializer(_BigIntSerializer())
  ..addSerializer(_Tuple2Serializer<BigInt, Tuple2<int, Base?>>())
  ..addSerializer(_Tuple2Serializer<int, Base?>())
  ..addSerializer(_UriSerializer());

void compute(List args) {
  final sendPort = args[0] as SendPort;
  final input = args[1] as List;
  final _ComplexType map = deserializeMap(input, _collection);
  final output = serializeMap(map, _collection);
  sendPort.send(output);
}

typedef _ComplexType = Map<Uri, List<Tuple2<BigInt, Tuple2<int, Base?>>>>;

class A extends Base {
  A(super.base);

  [@override](/user/override)
  bool operator ==(other) => other is A && other.base == base;
}

class B extends Base {
  final int x;

  B(super.base, this.x);

  [@override](/user/override)
  bool operator ==(other) => other is B && other.base == base && other.x == x;
}

class Base {
  final String base;

  Base(this.base);
}

class _ASerializer extends ObjectSerializer<A> {
  [@override](/user/override)
  A deserialize(Deserializer deserializer) {
    return A(
      deserializer.readObject(),
    );
  }

  [@override](/user/override)
  void serialize(Serializer serializer, A object) {
    serializer.writeObject(object.base);
  }
}

class _BigIntSerializer extends ObjectSerializer<BigInt> {
  [@override](/user/override)
  BigInt deserialize(Deserializer deserializer) {
    return BigInt.parse(deserializer.readObject());
  }

  [@override](/user/override)
  void serialize(Serializer serializer, BigInt object) {
    serializer.writeObject('$object');
  }
}

class _BSerializer extends ObjectSerializer<B> {
  [@override](/user/override)
  B deserialize(Deserializer deserializer) {
    return B(
      deserializer.readObject(),
      deserializer.readObject(),
    );
  }

  [@override](/user/override)
  void serialize(Serializer serializer, B object) {
    serializer.writeObject(object.base);
    serializer.writeObject(object.x);
  }
}

class _Tuple2Serializer<T1, T2> extends ObjectSerializer<Tuple2<T1, T2>> {
  [@override](/user/override)
  Tuple2<T1, T2> deserialize(Deserializer deserializer) {
    return Tuple2(
      deserializer.readObject(),
      deserializer.readObject(),
    );
  }

  [@override](/user/override)
  void serialize(Serializer serializer, Tuple2<T1, T2> object) {
    serializer.writeObject(object.item1);
    serializer.writeObject(object.item2);
  }
}

class _UriSerializer extends ObjectSerializer<Uri> {
  [@override](/user/override)
  Uri deserialize(Deserializer deserializer) {
    return Uri.parse(deserializer.readObject());
  }

  [@override](/user/override)
  void serialize(Serializer serializer, Uri object) {
    serializer.writeObject(object.toString());
  }
}

对象序列器

对象序列器 是一个支持缓存功能的序列器,可以序列化任何静态(泛型)复杂数据,这些数据可以表示为更简单的数据。

它允许你实现序列器以传递可以在隔离之间或甚至通过互联网传输的任何数据。其工作原理非常简单,对于每种数据类型,你需要实现自己的对象序列器。

实现对象序列器也非常简单。为此,你需要按严格的顺序写入数据,然后按相同的顺序读取这些数据。

示例

class _UriSerializer extends ObjectSerializer<Uri> {
  [@override](/user/override)
  Uri deserialize(Deserializer deserializer) {
    return Uri.parse(deserializer.readObject());
  }

  [@override](/user/override)
  void serialize(Serializer serializer, Uri object) {
    serializer.writeObject(object.toString());
  }
}

这并不是JSON序列器的替代品。在这种情况下,数据被序列化为所谓的流,并且如果需要,可以进行缓存。

例如,你可以序列化这样的数据:

typedef _ComplexType = Map<Uri, List<Tuple2<BigInt, Tuple2<int, Base?>>>>;

class A extends Base {
  A(super.base);

  [@override](/user/override)
  bool operator ==(other) => other is A && other.base == base;
}

class B extends Base {
  final int x;

  B(super.base, this.x);

  [@override](/user/override)
  bool operator ==(other) => other is B && other.base == base && other.x == x;
}

class Base {
  final String base;

  Base(this.base);
}

例如,这样的数据可以被序列化:

final _ComplexType map = {
  Uri.parse('package:animals'): [
    Tuple2(BigInt.parse('1'), Tuple2(1, A('Hello'))),
    Tuple2(BigInt.parse('2'), Tuple2(1, A('Hello'))),
  ],
  Uri.parse('package:zoo'): [
    Tuple2(BigInt.parse('1'), Tuple2(1, B('Goodbye', 41))),
    Tuple2(BigInt.parse('2'), Tuple2(2, null)),
    Tuple2(BigInt.parse('1'), Tuple2(1, A('Hello'))),
  ],
};

输出数据流:

[1, 4, 2, 4, 16, 6, 8, package:animals, 9, 9, 2, 12, 11, 14, 15, 16, 8, 1, 19, 12, 21, 2, 1, 24, 13, 26, 8, Hello, 29, 11, 31, 15, 33, 8, 2, 36, 12, 21, 39, 13, 26, 42, 16, 44, 8, package:zoo, 47, 9, 3, 50, 11, 14, 53, 12, 21, 56, 14, 58, 8, Goodbye, 61, 2, 41, 64, 11, 31, 67, 12, 69, 2, 2, 72, 6, 74, 11, 14, 77, 12, 21, 80, 13, 26]

完整的示例:

import 'dart:isolate';

import 'package:object_serializer/object_serializer.dart';
import 'package:object_serializer/serialize.dart';
import 'package:test/test.dart';
import 'package:tuple/tuple.dart';

Future<void> main() async {
  test(
    'Example',
    () async {
      final _ComplexType map = {
        Uri.parse('package:animals'): [
          Tuple2(BigInt.parse('1'), Tuple2(1, A('Hello'))),
          Tuple2(BigInt.parse('2'), Tuple2(1, A('Hello'))),
        ],
        Uri.parse('package:zoo'): [
          Tuple2(BigInt.parse('1'), Tuple2(1, B('Goodbye', 41))),
          Tuple2(BigInt.parse('2'), Tuple2(2, null)),
          Tuple2(BigInt.parse('1'), Tuple2(1, A('Hello'))),
        ],
      };

      final stream = serializeMap(map, _collection);

      //
      final port = ReceivePort();
      final isolate =
          await Isolate.spawn<List>(compute, [port.sendPort, stream]);
      final stream2 = await port.first as List;
      isolate.kill(priority: Isolate.immediate);

      //
      final _ComplexType result = deserializeMap(stream2, _collection);
      expect(result, map);
    },
  );
}

final _collection = ObjectSerializerCollection()
  ..addSerializer(ListSerializer<Tuple2<BigInt, Tuple2<int, Base?>>>())
  ..addSerializer(_ASerializer())
  ..addSerializer(_BSerializer())
  ..addSerializer(_BigIntSerializer())
  ..addSerializer(_Tuple2Serializer<BigInt, Tuple2<int, Base?>>())
  ..addSerializer(_Tuple2Serializer<int, Base?>())
  ..addSerializer(_UriSerializer());

void compute(List args) {
  final sendPort = args[0] as SendPort;
  final input = args[1] as List;
  final _ComplexType map = deserializeMap(input, _collection);
  final output = serializeMap(map, _collection);
  sendPort.send(output);
}

typedef _ComplexType = Map<Uri, List<Tuple2<BigInt, Tuple2<int, Base?>>>>;

class A extends Base {
  A(super.base);

  [@override](/user/override)
  bool operator ==(other) => other is A && other.base == base;
}

class B extends Base {
  final int x;

  B(super.base, this.x);

  [@override](/user/override)
  bool operator ==(other) => other is B && other.base == base && other.x == x;
}

class Base {
  final String base;

  Base(this.base);
}

class _ASerializer extends ObjectSerializer<A> {
  [@override](/user/override)
  A deserialize(Deserializer deserializer) {
    return A(
      deserializer.readObject(),
    );
  }

  [@override](/user/override)
  void serialize(Serializer serializer, A object) {
    serializer.writeObject(object.base);
  }
}

class _BigIntSerializer extends ObjectSerializer<BigInt> {
  [@override](/user/override)
  BigInt deserialize(Deserializer deserializer) {
    return BigInt.parse(deserializer.readObject());
  }

  [@override](/user/override)
  void serialize(Serializer serializer, BigInt object) {
    serializer.writeObject('$object');
  }
}

class _BSerializer extends ObjectSerializer<B> {
  [@override](/user/override)
  B deserialize(Deserializer deserializer) {
    return B(
      deserializer.readObject(),
      deserializer.readObject(),
    );
  }

  [@override](/user/override)
  void serialize(Serializer serializer, B object) {
    serializer.writeObject(object.base);
    serializer.writeObject(object.x);
  }
}

class _Tuple2Serializer<T1, T2> extends ObjectSerializer<Tuple2<T1, T2>> {
  [@override](/user/override)
  Tuple2<T1, T2> deserialize(Deserializer deserializer) {
    return Tuple2(
      deserializer.readObject(),
      deserializer.readObject(),
    );
  }

  [@override](/user/override)
  void serialize(Serializer serializer, Tuple2<T1, T2> object) {
    serializer.writeObject(object.item1);
    serializer.writeObject(object.item2);
  }
}

class _UriSerializer extends ObjectSerializer<Uri> {
  [@override](/user/override)
  Uri deserialize(Deserializer deserializer) {
    return Uri.parse(deserializer.readObject());
  }

  [@override](/user/override)
  void serialize(Serializer serializer, Uri object) {
    serializer.writeObject(object.toString());
  }
}

更多关于Flutter对象序列化插件object_serializer的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter对象序列化插件object_serializer的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


object_serializer 是一个用于 Flutter 的对象序列化和反序列化插件。它可以帮助你将 Dart 对象转换为 JSON 格式,或者将 JSON 数据解析为 Dart 对象。以下是如何使用 object_serializer 的基本步骤:

1. 添加依赖

首先,在你的 pubspec.yaml 文件中添加 object_serializer 依赖:

dependencies:
  flutter:
    sdk: flutter
  object_serializer: ^0.2.0  # 请根据最新版本号进行更新

然后运行 flutter pub get 来安装依赖。

2. 创建可序列化的类

你需要在你的 Dart 类中添加注解 @Serializable() 并实现 Serializable 接口。以下是一个简单的例子:

import 'package:object_serializer/object_serializer.dart';

@Serializable()
class User implements Serializable {
  String? name;
  int? age;

  @override
  Map<String, dynamic> toMap() {
    return {
      'name': name,
      'age': age,
    };
  }

  @override
  void fromMap(Map<String, dynamic> map) {
    name = map['name'];
    age = map['age'];
  }
}

3. 序列化对象

你可以使用 Serializer 类将对象序列化为 JSON 字符串:

import 'package:object_serializer/object_serializer.dart';

void main() {
  User user = User()
    ..name = 'John Doe'
    ..age = 30;

  Serializer serializer = Serializer();
  String jsonString = serializer.serialize(user);

  print(jsonString);  // 输出: {"name":"John Doe","age":30}
}

4. 反序列化对象

你也可以使用 Serializer 类将 JSON 字符串反序列化为对象:

import 'package:object_serializer/object_serializer.dart';

void main() {
  String jsonString = '{"name": "John Doe", "age": 30}';

  Serializer serializer = Serializer();
  User user = serializer.deserialize<User>(jsonString);

  print(user.name);  // 输出: John Doe
  print(user.age);   // 输出: 30
}

5. 处理复杂对象

如果你的类中包含嵌套对象或集合,你也可以使用 @Serializable() 注解来处理这些复杂结构。

@Serializable()
class Address implements Serializable {
  String? city;
  String? country;

  @override
  Map<String, dynamic> toMap() {
    return {
      'city': city,
      'country': country,
    };
  }

  @override
  void fromMap(Map<String, dynamic> map) {
    city = map['city'];
    country = map['country'];
  }
}

@Serializable()
class User implements Serializable {
  String? name;
  int? age;
  Address? address;

  @override
  Map<String, dynamic> toMap() {
    return {
      'name': name,
      'age': age,
      'address': address?.toMap(),
    };
  }

  @override
  void fromMap(Map<String, dynamic> map) {
    name = map['name'];
    age = map['age'];
    address = map['address'] != null ? Address()..fromMap(map['address']) : null;
  }
}

6. 处理集合

object_serializer 也可以处理集合对象,例如 ListMap

void main() {
  List<User> users = [
    User()..name = 'John Doe'..age = 30,
    User()..name = 'Jane Doe'..age = 25,
  ];

  Serializer serializer = Serializer();
  String jsonString = serializer.serialize(users);

  print(jsonString);

  List<User> deserializedUsers = serializer.deserialize<List<User>>(jsonString);
  print(deserializedUsers[0].name);  // 输出: John Doe
}
回到顶部