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
    }
  ]
}
第二步:

创建我们存放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: 
第四步:

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

flutter packages pub run build_runner build

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

flutter packages pub run build_runner watch

运行命令成功后,会生成对应的文件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);

}

  

第五步:

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

pubspec.yaml配置文件

assets:
    - assets/images/
    - assets/json/

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.
    );
  }
}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值