• Flutter 关于序列化JSON之json_serializable库的使用


    Flutter 序列化JSON数据

    前言:

    本来想着网上应该对这方面的讲解应该很全很完美的,但小弟愚昧,属实看不懂一些大佬的三言两语,无奈只能自己记录一下这个json_serializable库序列化的使用方法

    本文采用了本地化JSON数据来演示,实际项目中请使用正常HTTP请求数据替换
    第一步:

    创建我们要使用的JSON数据,这里使用的豆瓣电影的接口数据来进行测试,在我们的项目中创建assets/json/data.json目录,将测试数据放到该目录下的data.json当中,测试数据如下:

    目录:

    在这里插入图片描述

    代码:
    {
      "count": 2,
      "start": 0,
      "total": 3,
      "verify_users": [
        {
          "verify_roles": [
            "导演 / 编剧"
          ],
          "articles": [],
          "article_count": 0,
          "user": {
            "loc": null,
            "reg_time": "2022-07-30 00:51:39",
            "followed": false,
            "uid": "P03008",
            "name": "张吃鱼",
            "url": "https://www.douban.com/people/260180257/",
            "verify_type": 4,
            "abstract": "",
            "uri": "douban://douban.com/user/260180257",
            "id": "260180257",
            "avatar_side_icon": "",
            "medal_groups": [],
            "remark": "",
            "avatar_side_icon_id": "",
            "in_blacklist": false,
            "followers_count": 549,
            "is_club": false,
            "is_banned": false,
            "type": "user",
            "kind": "user",
            "avatar": "https://img2.doubanio.com/icon/up260180257-1.jpg"
          },
          "questions": [],
          "question_count": 0
        },
        {
          "verify_roles": [
            "演员"
          ],
          "articles": [],
          "article_count": 0,
          "user": {
            "loc": null,
            "reg_time": "2021-07-09 18:52:10",
            "followed": false,
            "uid": "241598444",
            "name": "史彭元",
            "url": "https://www.douban.com/people/241598444/",
            "verify_type": 4,
            "abstract": "",
            "uri": "douban://douban.com/user/241598444",
            "id": "241598444",
            "avatar_side_icon": "",
            "medal_groups": [],
            "remark": "",
            "avatar_side_icon_id": "",
            "in_blacklist": false,
            "followers_count": 2651,
            "is_club": false,
            "is_banned": false,
            "type": "user",
            "kind": "user",
            "avatar": "https://img2.doubanio.com/icon/up241598444-3.jpg"
          },
          "questions": [],
          "question_count": 0
        },
        {
          "verify_roles": [
            "剪辑"
          ],
          "articles": [],
          "article_count": 0,
          "user": {
            "loc": {
              "id": "108288",
              "name": "北京",
              "uid": "beijing"
            },
            "reg_time": "2017-11-20 14:42:36",
            "followed": false,
            "uid": "169913689",
            "name": "黄曾鸿辰",
            "url": "https://www.douban.com/people/169913689/",
            "verify_type": 4,
            "abstract": "",
            "uri": "douban://douban.com/user/169913689",
            "id": "169913689",
            "avatar_side_icon": "",
            "medal_groups": [],
            "remark": "",
            "avatar_side_icon_id": "",
            "in_blacklist": false,
            "followers_count": 235,
            "is_club": false,
            "is_banned": false,
            "type": "user",
            "kind": "user",
            "avatar": "https://img2.doubanio.com/icon/up169913689-2.jpg"
          },
          "questions": [],
          "question_count": 0
        }
      ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    第二步:

    创建我们存放jsonModel数据的目录,我这边目录结构为:lib/json/dou_model.dart,之后使用网站工具生成我们的转换结构数据,复制生成的结果到dou_model.dart文件中
    网站地址:https://caijinglong.github.io/json2dart/index_ch.html
    在这里插入图片描述
    注意:当你将代码复制过来后,会出现报红的报错的问题,这里我们来修改一下,首先将第二行的part 'entity.g.dart';中的entity.g.dart修改为dou_model.g.dart,同时可以将类名换个相对应的名字,part 'dou_model.g.dart$DouModelFromJson等多个报错,这个是因为我们没有使用json_serializable库来生成对应的文件而导致的。

    报错截图:
    在这里插入图片描述

    第三步:

    pubspec.yaml中引入相对应的库,这里库的版本我就不做指明了,这样就会按照flutterSDK的版本来自行检索最适合的库。

    dependencies:
      ........
      # 创建json序列化和反序列化注释
      json_annotation:
      
    dev_dependencies:
      ........
      # 为bean文件生成对应的json解析函数
      json_serializable: 
      # 运行时框架,使用之后可以使用更多扩展命令
      build_runner: 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    第四步:

    做完以上步骤后,我们就可以在命令行中使用命令来创建对应之前报错的dou_model.g.dart库了。
    命令为:

    flutter packages pub run build_runner build
    
    • 1

    该指令是一次性生成JSON序列化的代码。
    如果感觉每次更改Model时都需要执行一次性生成指令比较繁琐,这时可以新开一个命令行窗口使用下面的持续生成指令,该指令会一直监听文件的创建并生成对应的model文件:

    flutter packages pub run build_runner watch
    
    • 1

    运行命令成功后,会生成对应的文件dou_model.g.dart,这个时候,对应的报错信息会逐渐消失掉,出现一个新的报错:
    在这里插入图片描述
    在这里,我们可以将图中的with _$DouModelSerializerMixin等混淆的Mixin报错信息给删除掉,因为暂时我们是用不到的,这些都修改完后,报错信息应该是没有了。

    完整代码

    import 'package:json_annotation/json_annotation.dart'; 
      
    part 'dou_model.g.dart';
    
    
    ()
      class DouModel extends Object {
    
      (name: 'count')
      int count;
    
      (name: 'start')
      int start;
    
      (name: 'total')
      int total;
    
      (name: 'verify_users')
      List<Verify_users> verifyUsers;
    
      DouModel(this.count,this.start,this.total,this.verifyUsers,);
    
      factory DouModel.fromJson(Map<String, dynamic> srcJson) => _$DouModelFromJson(srcJson);
    
    }
    
      
    ()
      class Verify_users extends Object{
    
      (name: 'verify_roles')
      List<String> verifyRoles;
    
      (name: 'articles')
      List<dynamic> articles;
    
      (name: 'article_count')
      int articleCount;
    
      (name: 'user')
      User user;
    
      (name: 'questions')
      List<dynamic> questions;
    
      (name: 'question_count')
      int questionCount;
    
      Verify_users(this.verifyRoles,this.articles,this.articleCount,this.user,this.questions,this.questionCount,);
    
      factory Verify_users.fromJson(Map<String, dynamic> srcJson) => _$Verify_usersFromJson(srcJson);
    
    }
    
      
    ()
      class User extends Object{
    
      (name: 'reg_time')
      String regTime;
    
      (name: 'followed')
      bool followed;
    
      (name: 'uid')
      String uid;
    
      (name: 'name')
      String name;
    
      (name: 'url')
      String url;
    
      (name: 'verify_type')
      int verifyType;
    
      (name: 'abstract')
      String abstract;
    
      (name: 'uri')
      String uri;
    
      (name: 'id')
      String id;
    
      (name: 'avatar_side_icon')
      String avatarSideIcon;
    
      (name: 'medal_groups')
      List<dynamic> medalGroups;
    
      (name: 'remark')
      String remark;
    
      (name: 'avatar_side_icon_id')
      String avatarSideIconId;
    
      (name: 'in_blacklist')
      bool inBlacklist;
    
      (name: 'followers_count')
      int followersCount;
    
      (name: 'is_club')
      bool isClub;
    
      (name: 'is_banned')
      bool isBanned;
    
      (name: 'type')
      String type;
    
      (name: 'kind')
      String kind;
    
      (name: 'avatar')
      String avatar;
    
      User(this.regTime,this.followed,this.uid,this.name,this.url,this.verifyType,this.abstract,this.uri,this.id,this.avatarSideIcon,this.medalGroups,this.remark,this.avatarSideIconId,this.inBlacklist,this.followersCount,this.isClub,this.isBanned,this.type,this.kind,this.avatar,);
    
      factory User.fromJson(Map<String, dynamic> srcJson) => _$UserFromJson(srcJson);
    
    }
    
      
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    第五步:

    接下来我们可以实践我们的Model到底创建成功了么,到底能不能使用,首先记得在pubspec.yaml中配置一下使用本地化文件的规则,在这里我直接在一个example示例工程的代码上去实践测试了,大家可以以这个为参考代入到自己项目中:

    pubspec.yaml配置文件

    assets:
        - assets/images/
        - assets/json/
    
    • 1
    • 2
    • 3

    example.dart示例代码

    import 'dart:convert';
    
    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart' show rootBundle;
    import 'package:example/json/userInfo_data_model.dart';
    
    class MyHomePage extends StatefulWidget {
      const MyHomePage({Key? key, required this.title}) : super(key: key);
    
      final String title;
    
      
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      int _counter = 0;
    
      void _incrementCounter() {
        _getData();
      }
    
      Future _getData() async {
        return await rootBundle.loadString('assets/json/data.json');
      }
    
      Future loadJSDataModel() async {
        String jsonString = await _getData();
        final jsonResponse = json.decode(jsonString);
        UserInfo model = UserInfo.fromJson(jsonResponse);
        print(model.data.nickName);
      }
    
      
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                const Text(
                  'You have pushed the button this many times:',
                ),
                Text(
                  '$_counter',
                  style: Theme.of(context).textTheme.headline4,
                ),
              ],
            ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: loadJSDataModel,
            tooltip: 'Increment',
            child: const Icon(Icons.add),
          ), // This trailing comma makes auto-formatting nicer for build methods.
        );
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    OK,以上即是关于序列化Json之json_serializable库的使用的全部内容了,如果大家有什么问题,欢迎留言~

  • 相关阅读:
    青年领袖分论坛精彩回顾 | 第二届始祖数字化可持续发展峰会
    哪个牌子除甲醛产品效果好 目前除甲醛最好的净化器
    软件测试之功能测试
    基于单片机设计的自动门控制系统
    【Linux】第十三站:进程状态
    cmake学习笔记 二
    Spring如何解决循环依赖
    【linux命令讲解大全】099.Linux常用文件传输命令详解
    springboot系列(十九):如何集成redis?不会我教你 | 超级详细,建议收藏
    什么是原生IP与广播IP?如何区分判定?
  • 原文地址:https://blog.csdn.net/qq_38774121/article/details/126587662