美文网首页
Flutter 高效率JSON转Model

Flutter 高效率JSON转Model

作者: czero1995 | 来源:发表于2020-11-11 10:27 被阅读0次

    背景


    在开发过程中,服务端通常返回的是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
    

    [图片上传失败...(image-b6fc38-1605061601267)]

    在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<MoreData> 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

    相关文章

      网友评论

          本文标题:Flutter 高效率JSON转Model

          本文链接:https://www.haomeiwen.com/subject/xrkebktx.html