Dart中JSON的序列化和反序列化状态

问题描述 投票:3回答:7

我在C#上进行序列化方面有很好的经验,在搜索和测试一些Dart库之后,我觉得一般都没有一个真正令人满意的答案。

  1. 我想知道Dart中JSON的序列化/反序列化的当前状态吗?
  2. 我们将来应该期待什么?
  3. 这最终是由语言本身支持的吗?
  4. 目前最好的做法是什么?

我也喜欢任何阅读此内容的人,请发布任何新信息,即使帖子变老了。

json serialization dart
7个回答
4
投票

目前,最好的选择可能是使用Smoke库。

它是Mirrors功能的一个子集,但同时具有基于Mirrors和基于Codegen的实现。它由PolymerDart团队编写,因此它与我们将获得的“官方”接近。

在开发过程中,它将使用基于镜像的编码/解码;但是对于发布,您可以创建一个生成代码的小型转换器。

塞思拉德创造了a code sample here,我extended slightly支持儿童对象:

abstract class Serializable {
  static fromJson(Type t, Map json) {
    var typeMirror = reflectType(t);
    T obj = typeMirror.newInstance(new Symbol(""), const[]).reflectee;
    json.forEach((k, v) {
      if (v is Map) {
        var d = smoke.getDeclaration(t, smoke.nameToSymbol(k));
        smoke.write(obj, smoke.nameToSymbol(k), Serializable.fromJson(d.type, v));
      } else {
        smoke.write(obj, smoke.nameToSymbol(k), v);
      }
    });
    return obj;
  }

  Map toJson() {
    var options = new smoke.QueryOptions(includeProperties: false);
    var res = smoke.query(runtimeType, options);
    var map = {};
    res.forEach((r) => map[smoke.symbolToName(r.name)] = smoke.read(this, r.name));
    return map;
  }
}

目前,不支持在Smoke中获取泛型类型信息(例如,支持List);不过我在这里提出了一个案例:

https://code.google.com/p/dart/issues/detail?id=20584

在实施这个问题之前,实现你想要的“好”并不可行;但我希望它很快就会实施;因为做一些像JSON序列化那样基本的东西取决于它!

Alan Knight也在开发一个Serialization包,但是我发现它缺乏对将日期时间转换为字符串这么简单的事情的支持,而且对于那些基本的东西来说,解决方案似乎相当冗长。

现在,在我自己的项目中,我已经使用了代码生成我们的json序列化(以toMap和fromMap方法的形式),因为我们已经为服务器端提供了C#版本的类。如果时间允许,我想整理这些代码并制作一个NuGet包(它支持嵌套对象,数组,不包括属性等)。


2
投票

目前,您可以使用redstone_mapper在Dart对象和JSON之间进行转换。这个包是Redstone.dart框架的插件,但可以在没有它的情况下使用。 Pub还有其他选择


1
投票

没有“一刀切”的序列化解决方案。有关冗长的讨论,请参阅https://groups.google.com/a/dartlang.org/forum/#!searchin/misc/serialization/misc/0pv-Uaq8FGI/5iMrzOrlUKwJ


1
投票

通常,从基于镜像的解决方案转向基于代码生成的解决方案,特别是基于package:source_gen。这是因为codegen可以提供比镜像更小更快的运行时。

使用codegen进行序列化的一个包是built_value:

https://github.com/google/built_value.dart

使用built_value,您的模型类如下所示:

abstract class Account implements Built<Account, AccountBuilder> {
  static Serializer<Account> get serializer => _$accountSerializer;

  int get id;
  String get name;
  BuiltMap<String, JsonObject> get keyValues;

  factory Account([updates(AccountBuilder b)]) = _$Account;
  Account._();
}

请注意,built_value不仅仅是序列化 - 它还提供了operator ==,hashCode,toString和一个构建器类。


1
投票

我意识到这是一个老问题,但是如果你在2019年来到这里,我发现了一个很好的代码生成解决方案:

https://pub.dartlang.org/packages/json_serializable

从github存储库来看,我认为这也是“官方”解决方案。

它使用注释@JsonSerializable@JsonKey来控制序列化。根据我的经验,它似乎完美地处理继承等。它在您构建项目时自动生成序列化和分散功能。


0
投票

我目前正在使用exportable进行序列化并使用morph进行反序列化。


0
投票

Dart具有对地图,列表和基元类型进行编码和解码的实现。你可以在this article找到例子。如果你正在寻找速度,这可能是最快的,因为它们在本机C / C ++中实现了json转换 - 作者创建的库通常用Dart编写,并且速度会慢一些。

JSON.encodeJSON.decode的缺点是除了上面提到的没有toJson和fromJson方法之外,他们不能采取任何其他对象。

幸运的是,有些库可以利用Dart中的反射来简化它。我自己创建了一个小型库,可以在没有任何额外代码的情况下对JSON进行序列化和反序列化。你可以找到它here。除了针对您的问题的上述解决方案,您可以在Dart pub网站上找到许多解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.