云社区 博客 博客详情

Flutter JSON转Model

SegmentFault思否 发表于 2020-11-11 00:56:06 2020-11-11
0
0

【摘要】 背景在开发过程中,服务端通常返回的是JSON格式的数据,对于Web开发人员(JavaScript、TypeScript)中,可以直接拿到JSON数据来做我们的逻辑。JSON本身起源于JavaScript,JavaScript解析处理JSON有天然的优势但在像 Java、Dart 等强类型语言中,我们需要将JSON数据转模型对象来使用。一般情况下,我们会使用一些第三方库来动态转...

背景


在开发过程中,服务端通常返回的是JSON格式的数据,对于Web开发人员(JavaScript、TypeScript)中,可以直接拿到JSON数据来做我们的逻辑。

JSON本身起源于JavaScript,JavaScript解析处理JSON有天然的优势

但在像 Java、Dart 等强类型语言中,我们需要将JSON数据转模型对象来使用。

  • 一般情况下,我们会使用一些第三方库来动态转化Model,但是Flutter中没有像Java的GSON/Jackson这类JSON序列化库。
  • 因为Flutter中禁用运行时反射。官方解释是运行时反射会干扰Dart的Tree Shaking,使用Tree Shaking可以在Release版中去除未使用的代码,这可以显著优化应用程序的大小。
  • 由于反射会默认应用到Dart的反射功能,而正因如此也就无法实现动态化转Model的功能。

序列化的几种方案


Flutter官方推荐的有两种序列化方案:https://flutterchina.club/json/

  1. 小项目手动序列化,这种方案比较简单,比较适合小项目简单的JSON转换,但项目庞大,或者多人合作,容易出错,也不易维护。

    Flutter有一个内置dart:convert库
    使用 dart:convert手动序列化JSON
  2. 在大中型项目中使用代码生成,需要用到以下三个依赖包,通过代码自动生成的方式,生成模型。这种方案易维护,由于序列化数据代码不再需要手动编写或者维护,你可以将序列化 JSON 数据在运行时的异常风险降到最低;

转换流程


  1. 在pubspec.yaml中添加依赖
json_annotation: ^3.1.0
json_serializable: ^3.5.0
build_runner: ^1.0.0

在Android Stuido中执行Pub get

  1. 新建模型类(mode/demo_model.dart)
class DemoModel{ }
  1. 在网页上把后端请求到的JSON数据转换成Model:

    https://czero1995.github.io/json-to-model/:网站转换支持无限层次嵌套复杂对象的转换

    //p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/904e6b0f3048460cbdd7018b06b67ad3~tplv-k3u1fbpfcp-zoom-1.image

  • 比如将以下JSON数据复制到网页上(左边):
{
  "code": 0,
  "data": { "avatar": "xxx.png", "id": 7, "float":0.1, "is_deleted": false, "nickname": "nickName", "openId": null, "phone": "13641418383", "store_ids": [1,2], "updated": "2020-11-05 11:53:10", "more":[{"a":1,"b":"b","c":{"c1":0.2,"c2":2}}]
  }
}
  • 然后转换成Model数据(右边)
import 'package:json_annotation/json_annotation.dart';
part 'demo_model_data.g.dart'; 
@JsonSerializable(explicitToJson: true)
class DemoModelModel { DemoModelData data; DemoModelModel({ this.data, this.code, this.message }); factory DemoModelModel.fromJson(Map<String, dynamic> json) => _$DemoModelModelFromJson(json); Map<String, dynamic> toJson() => _$DemoModelModelToJson(this);
}

@JsonSerializable(explicitToJson: true)
class DemoModelData { String avatar; int id; double float; bool is_deleted; String nickname; var openId; String phone; List<int> store_ids; String updated; List more; DemoModelData({ this.avatar, this.id, this.float, this.is_deleted, this.nickname, this.openId, this.phone, this.store_ids, this.updated, this.more, });
  factory DemoModelData.fromJson(Map<String, dynamic> json) => _$DemoModelDataFromJson(json);
  Map<String, dynamic> toJson() => _$DemoModelDataToJson(this);
}

@JsonSerializable(explicitToJson: true) 
class MoreData{ int a; String b; CData c; MoreData({ this.a, this.b, this.c, }); factory MoreData.fromJson(Map<String, dynamic> json) => _$MoreDataFromJson(json); Map<String, dynamic> toJson() => _$MoreDataToJson(this);
}

@JsonSerializable(explicitToJson: true) 
class CData{ double c1; int c2; CData({ this.c1, this.c2, }); factory CData.fromJson(Map<String, dynamic> json) => _$CDataFromJson(json); Map<String, dynamic> toJson() => _$CDataToJson(this);
}

再将转换之后的数据复制出来覆盖到demo_model.dart文件上

  1. 执行build_runner

在项目终端下执行命令:

flutter pub run build_runner build

执行完成后,会生成demo_model.g.dart文件

整个执行流程如下

//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8bc6bb3edb75410397af822c881b1316~tplv-k3u1fbpfcp-zoom-1.image

文章来源: segmentfault.com,作者:czero1995,版权归原作者所有,如需转载,请联系作者。

原文链接:segmentfault.com/a/1190000037784724

登录后可下载附件,请登录或者注册

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:huaweicloud.bbs@huawei.com进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
评论文章 //点赞 收藏 0
点赞
分享文章到微博
分享文章到朋友圈

上一篇:深入浅出git(二)——分支

下一篇:Git 常用命令参考手册

评论 (0)


登录后可评论,请 登录注册

评论