使用 Flutter 反序列化 JSON 的一些选项

本文介绍了Flutter中反序列化JSON的三种方法:手写构造函数、json_serializable和built_value。手写构造函数最简单但需要手动维护,json_serializable能自动生成fromJson和toJson方法,而built_value除了序列化还提供了不可变性、toString等额外功能。选择哪种方法取决于项目规模和需求。
摘要由CSDN通过智能技术生成

文 / Andrew Brogdon

来源 | 谷歌开发者 公众号

在某种程度上,大多数应用都需要与外界互动,并从在线终端地址获取数据。借助 Dart 的 http 包,发出 HTTPS get 请求以获取天气预报或世界杯最终比分变得非常简单:

1    import 'dart:async';    

2    import 'package:http/http.dart' as http; 

3

4    final response = await http.get(myEndpointUrl);    

5    if (response.statusCode == 200) {    

6    // use the data in response.body    

7    } else {    

8    // handle a failed request    

9    } 

response.body 中的数据可能是 JSON 字符串,而我们还需要完成一些工作,才能将其用于微件。首先,您需要将字符串解析为更易于管理的 JSON 表示形式。然后,您必须将该表示形式转化为模型或其他一些强类型变量,如此一来,您就可以有效地使用这些字符串。

幸运的是,Dart 团队和社群对 JSON 已进行过诸多讨论,并且能够提供解决方案。我会按照复杂性从低到高的顺序介绍三种解决方案,分别是手写构造函数、json_serializable 和 built_value。

使用全部三种方法将数据反序列化的调用非常相似。手写构造函数和 json_serializable 的代码行如下所示:

1    final myObject = SimpleObject.fromJson(json.decode(aJsonString));

built_value 的反序列化调用如下所示:

1    final myObject = serializers.deserializeWith(  

2        SimpleObject.serializer, json.decode(aJsonString));  

真正的区别是,在该 “SimpleObject” 类中为您生成多少代码,以及这些代码有何作用。

手写构造函数

复杂性最低的方法:不为您生成代码。

您可以做自己想做的任何事,但您必须进行维护。

json_serializable

为您生成 fromJson 构造函数和 toJson 方法。

在构建应用之前,您需要在项目中加入若干个包,并使用 source_gen 生成部分文件。

对所生成的资源进行自定义可能会很棘手。

built_value

为序列化、不可变性、toString 方法、hashCode 属性等生成代码。这是具备诸多功能的重量级解决方案。

与 json_serializable 一样,您需要导入许多包并使用 source_gen。

拥有基于插件的可扩展序列化架构。

对实例创建和可变性等方面有见解。

正如下文所述,您适合使用哪个内容库其实取决于项目详情,特别是项目大小和状态管理方法。对拥有一位维护者的兴趣项目来说,手写构造函数很有帮助,而由庞大分布式团队(他们需要不可变模型来保持逻辑清晰)构建的应用则会真正从 “built_value” 受益。

不过,现在我们还是从头开始介绍:将 JSON 从字符串解析为更方便使用的内存表示形式。无论您之后决定采取哪种方法,相关流程中的这一步都是一样的。

解析 JSON

您可以使用 dart:convert 库将 JSON 字符串转换为中间格式:

1    import 'dart:convert'; 

2

3    try {

4        final parsed = json.decode(aJsonStr);

5    } on FormatException catch (e) { 

6        print("That string didn't look like Json.");

7    } on NoSuchMethodError catch (e) { 

8        print('That string was null!');

9    } 

如果该字符串包含有效的 JSON,系统会返回对 List 或 Map

1    final dynamicListOfInts = json.decode(aJsonArrayOfInts);

2

3    // Create a strongly typed list with references to the data that are casted

4    // immediately. This is probably the better approach for data model classes.

5    final strongListOfInts = List<int>.from(dynamicListOfInts); 

6

7    // Or create a strongly typed list with references that will be lazy-casted 

8    // when used.

9    final anotherStrongListOfInts = List<int>.from(dynamicListOfInts);

更复杂的有效负载才是有趣之处。将 Map

手写构造函数

我们必须从某个地方开始,对吗?如果您有一个小应用,而且数据也不是很复杂,那么自行编写采用 Map

1    {

2        "aString": "Blah, blah, blah.", 

3        "anInt": 1,

4        "aDouble": 1.0,

5        "aListOfStrings": ["one", "two", "three"],

6        "aListOfInts": [1, 2, 3], 

7        "aListOfDoubles": [1.0, 2.0, 3.0]

8    }

匹配类的代码可能如下所示:

1    class SimpleObject {
   

2        const SimpleObject({

3            this.aString,

4</
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值