一篇文章了解Flutter Json系列化和反序列化

目录

  • 一. 使用dart:convert实现JSON格式编解码
    • 1. 生成数据模型类
    • 2. 将JSON数据转化成数据模型类
    • 3. 数据模型类转化成JSON字符串
  • 二、借助`json_serializable`实现Json编解码
    • 1.添加`json_annotation`、`build_runner`、`json_serializable`依赖
    • 2. 创建一个数据模型类
    • 3. 使用命令行生成JSON序列化和反序列化的代码:
    • 4. 将JSON数据转化成数据模型类
    • 5. 数据模型类转化成JSON字符串
  • 三、 两种方案对比

一. 使用dart:convert实现JSON格式编解码

要在Flutter中解析JSON数据,您可以使用Flutter的内置库dart:convert。以下是一个简单的示例,演示如何解析JSON数据:

假设您有以下JSON数据(包含JSON数组和数据模型嵌套)

{"name": "John","age": 30,"email": "john@example.com","car": [{"name": "保时捷","price": 500},{"name": "奔驰","price": 1000}]
}

1. 生成数据模型类

数据模型生成网址: https://javiercbk.github.io/json_to_dart/
在这里插入图片描述

目前发现的缺点最外层是数组格式json生成的数据模型有问题,如下图:
在这里插入图片描述

class UserBean {String? name;int? age;String? email;List<Car>? car;UserBean({this.name, this.age, this.email, this.car});UserBean.fromJson(Map<String, dynamic> json) {name = json['name'];age = json['age'];email = json['email'];if (json['car'] != null) {car = <Car>[];json['car'].forEach((v) {car!.add(new Car.fromJson(v));});}}Map<String, dynamic> toJson() {final Map<String, dynamic> data = new Map<String, dynamic>();data['name'] = this.name;data['age'] = this.age;data['email'] = this.email;if (this.car != null) {data['car'] = this.car!.map((v) => v.toJson()).toList();}return data;}
}class Car {String? name;int? price;Car({this.name, this.price});Car.fromJson(Map<String, dynamic> json) {name = json['name'];price = json['price'];}Map<String, dynamic> toJson() {final Map<String, dynamic> data = new Map<String, dynamic>();data['name'] = this.name;data['price'] = this.price;return data;}
}

2. 将JSON数据转化成数据模型类

  • 导入dart:convert库:
import 'dart:convert';
  • 使用json.decode()方法解析JSON数据为一个Map对象:
 Map<String, dynamic> map = json.decode(jsonString);
  • map对象转化成数据模型类
  UserBean userBean = UserBean.fromJson(userBeanMap);

3. 数据模型类转化成JSON字符串

  • 导入dart:convert库:
import 'dart:convert';
  • 将数据模型类转化成map对象
Map<String,dynamic> userBeanMap1 = userBean.toJson();
  • Map对象转化成JSON字符串
String  userBeanJson = jsonEncode(userBeanMap1);

二、借助json_serializable实现Json编解码

1.添加json_annotationbuild_runnerjson_serializable依赖

dependencies:flutter:sdk: flutterjson_annotation: ^4.8.1dev_dependencies:...build_runner: '>=2.3.0 <4.0.0' json_serializable: ^6.6.2  ...

2. 创建一个数据模型类

serializable数据模型生成网址: https://caijinglong.github.io/json2dart/index_ch.html
在这里插入图片描述

import 'package:json_annotation/json_annotation.dart'; part 'user_bean.g.dart';()class UserBean extends Object {(name: 'name')String name;(name: 'age')int age;(name: 'email')String email;(name: 'car')List<Car> car;UserBean(this.name,this.age,this.email,this.car,);factory UserBean.fromJson(Map<String, dynamic> srcJson) => _$UserBeanFromJson(srcJson);Map<String, dynamic> toJson() => _$UserBeanToJson(this);}()class Car extends Object {(name: 'name')String name;(name: 'price')int price;Car(this.name,this.price,);factory Car.fromJson(Map<String, dynamic> srcJson) => _$CarFromJson(srcJson);Map<String, dynamic> toJson() => _$CarToJson(this);}

serializable数据模型3个要素:

  1. 导入json_annotation库注解,用于标识JSON字段和生成代码的相关信息。使用@JsonSerializable()注解类,用 @JsonKey(name: 'xx')注解字段,xx必须与JSON字段一一对应
  2. part 'xx.g.dart'; xx是当前文件名称,缺失这个配置或者配置错误,都会导致生成文件出错;
  3. _$XXFromJson_$XXToJson是通过build_runner自动生成的代码,用于序列化和反序列化JSON数据。

3. 使用命令行生成JSON序列化和反序列化的代码:

flutter packages pub run build_runner build

这个命令会为你的数据模型类生成user.g.dart文件,其中包含了_$XXFromJson_$XXToJson方法的实现。
XX.g.dart默认会生成在模型类的同级目录。

  1. 如果有其他.g文件存在影响,可用这个命令flutter packages pub run build_runner build --delete-conflicting-outputs
  2. 如果build成功,但是没有文件生成,需要检查part ‘xx.g.dart’;是否缺失或者配置错误

4. 将JSON数据转化成数据模型类

  • 导入dart:convert库:
import 'dart:convert';
  • 使用json.decode()方法解析JSON数据为一个Map对象:
 Map<String, dynamic> map = json.decode(jsonString);
  • map对象转化成数据模型类
  UserBean userBean = UserBean.fromJson(userBeanMap);

5. 数据模型类转化成JSON字符串

  • 导入dart:convert库:
import 'dart:convert';
  • 将数据模型类转化成map对象
Map<String,dynamic> userBeanMap1 = userBean.toJson();
  • Map对象转化成JSON字符串
String  userBeanJson = jsonEncode(userBeanMap1);

三、 两种方案对比

相同点:

  1. Map对象转化成JSON字符串以及将Map对象转化成JSON字符串都是依赖convert;
  2. JSON字符串和数据模型之间转化都需要借助Map对象;

不同点:

  1. 处理数据模型字段变更场景,方案二修改代码较少,出错的概率更低:

方案一需要添加或者修改字段并且手动修改fromJsontoJson方法;
方案二需要添加或者修改字段,添加相关注解,并重新使用命令行生成JSON序列化和反序列化的代码;

  1. Json最外层的数据结构是数组类型

方案一不支持
方案二支持

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/219445.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

819. 最常见的单词

819. 最常见的单词 Java&#xff1a;split() 过滤 class Solution {public String mostCommonWord(String paragraph, String[] banned) {String s paragraph.replaceAll("\\p{Punct}", " "); // 去除所有标点符号String arr[] s.split(" "…

遗传算法应用-- 栅格法机器人路径规划

文章目录 一、遗传算法1.1 编码与解码1.2 选择算子-轮盘赌法1.3 交叉算子1.4 变异算子1.5 遗传算法流程1.6 基于遗传算法的栅格法机器人路径规划 二、采用模拟退火算法改善适应度函数 一、遗传算法 遗传算法 (Genetic AIgorithm, 简称 GA)起源于对生物系统所进行的计算机模拟研…

1.3 第一个C程序

一、Dev-C的安装 下载地址&#xff1a;https://sourceforge.net/projects/orwelldevcpp/ 二、Dev-C简单的使用 2.1 首次打开配置 2.2 第一个程序的编辑、编译、运行 三、Hello Word程序讲解 3.1 程序框架 几乎所有的程序都需要这一段代码 3.2 输出 printf("Hello World…

workflow系列教程(4)Parallel并联任务流

往期教程 如果觉得写的可以,请给一个点赞关注支持一下 观看之前请先看,往期的博客教程,否则这篇博客没办法看懂 workFlow c异步网络库编译教程与简介 C异步网络库workflow入门教程(1)HTTP任务 C异步网络库workflow系列教程(2)redis任务 workflow系列教程(3)Series串联任务流…

AICore 带来了 Android 专属的 AI 能力,它要解决什么?采用什么架构思路?

前言 Google 最近发布的 Gemini 模型在全球引起了巨大反响&#xff0c;其在多模态领域的 Video demo 无比震撼。对于 Android 开发者而言&#xff0c;其中最振奋人心的消息莫过于 Gemini Nano 模型将内置到 Android 系统当中&#xff0c;并开放给开发者使用。 事实上&#xf…

【产品经理】产品专业化提升路径

产品专业化就是上山寻路&#xff0c;梳理一套作为产品经理的工作方法。本文作者从设计方法、三基座、专业强化、优秀产品拆解、零代码这五个方面&#xff0c;对产品经理的产品专业化进行了总结归纳&#xff0c;一起来看一下吧。 产品专业化就是上山寻路&#xff0c;梳理一套作为…

接口自动化测试框架【AIM】

最近在做公司项目的自动化接口测试&#xff0c;在现有几个小框架的基础上&#xff0c;反复研究和实践&#xff0c;搭建了新的测试框架。利用业余时间&#xff0c;把框架总结了下来。 AIM框架介绍 AIM&#xff0c;是Automatic Interface Monitoring的简称&#xff0c;即自动化…

c++ websocket 协议分析与实现

前言 网上有很多第三方库&#xff0c;nopoll,uwebsockets,libwebsockets,都喜欢回调或太复杂&#xff0c;个人只需要在后端用&#xff0c;所以手动写个&#xff1b; 1:环境 ubuntu18 g(支持c11即可) 第三方库:jsoncpp,openssl 2:安装 jsoncpp 读取json 配置文件 用 自动安装 网…

docker小白第五天

docker小白第五天 docker的私有库 有些涉密的信息代码不能放在阿里云的镜像仓库&#xff0c;因此需要构建一个个人内网专属的私有库&#xff0c;将镜像或者容器代码进行推送保存。 下载镜像docker registry 执行代码docker pull registry&#xff0c;用于搭建私服前的准备。…

微信小程序---使用npm包安装Vant组件库

在小程序项目中&#xff0c;安装Vant 组件库主要分为如下3步: 注意&#xff1a;如果你的文件中不存在pakage.json&#xff0c;请初始化一下包管理器 npm init -y 1.通过 npm 安装(建议指定版本为1.3.3&#xff09; 通过npm npm i vant/weapp1.3.3 -S --production 通过y…

EasyExcel 简单导入

前边写过使用easyexcel进行简单、多sheet页的导出。今天周日利用空闲写一下对应简单的导入。 重点&#xff1a;springboot、easyExcel、桥接模式&#xff1b; 说明&#xff1a;本次使用实体类student&#xff1a;属性看前边章节内容&#xff1b; 1、公共导入service public …

gitee提交代码步骤介绍(含git环境搭建)

1、gitee官网地址 https://gitee.com; 2、Windows中安装git环境 参考博客&#xff1a;《Windows中安装Git软件和TortoiseGit软件》&#xff1b; 3、设置用户名和密码 这里的用户名和密码就是登录gitee网站的用户名和密码如果设置错误&#xff0c;可以在Windows系统的“凭据管理…

C#面试题

目录 基本概念 装箱和拆箱 1、装箱拆箱的“箱”是什么&#xff0c;“箱”存放在哪里&#xff1f; 2、装箱快还是拆箱快&#xff1f; 3、装箱和拆箱有什么性能影响&#xff1f; 值类型和引用类型分别是哪些 访问权限修饰符 委托(delegate) 什么是委托链 委托链用途 事件…

【C语言】实战项目——通讯录

引言 学会创建一个通讯录&#xff0c;对过往知识进行加深和巩固。 文章很长&#xff0c;要耐心学完哦&#xff01; ✨ 猪巴戒&#xff1a;个人主页✨ 所属专栏&#xff1a;《C语言进阶》 &#x1f388;跟着猪巴戒&#xff0c;一起学习C语言&#x1f388; 目录 引言 实战 建…

VLAN间的通讯---三层交换

一.三层交换 1.概念 使用三层交换技术实现VLAN间通信 三层交换二层交换 三层转发 2.基于CEF的MLS CEF是一种基于拓补转发的模型 转发信息库&#xff08;FIB&#xff09;临接关系表 转发信息库&#xff08;FIB&#xff09;可以理解为路由表 邻接关系表可以理解为MAC地址表…

Linux驱动(中断、异步通知):红外对射,并在Qt StatusBus使用指示灯进行显示

本文工作&#xff1a; 1、Linux驱动与应用程序编写&#xff1a;使用了设备树、中断、异步通知知识点&#xff0c;实现了红外对射状态的异步信息提醒。 2、QT程序编写&#xff1a;自定义了一个“文本指示灯”类&#xff0c;并放置在QMainWidget的StatusBus中。 3、C与C混合编程与…

【华为数据之道学习笔记】5-4 数据入湖方式

数据入湖遵循华为信息架构&#xff0c;以逻辑数据实体为粒度入湖&#xff0c;逻辑数据实体在首次入湖时应该考虑信息的完整性。原则上&#xff0c;一个逻辑数据实体的所有属性应该一次性进湖&#xff0c;避免一个逻辑实体多次入湖&#xff0c;增加入湖工作量。 数据入湖的方式…

Android Studio好用的插件推荐

目录 一、插件推荐 二、如何下载 1.点击File—>Settings ​2.点击Plugins然后进行搜索下载 三、Android Studio 模板 一、插件推荐 这个插件可以为您自动生成Parcelable代码。Parcelable是一种用于在Android组件之间传递自定义对象的机制&#xff0c;但手动编写Parcela…

RabbitMQ搭建集群环境、配置镜像集群、负载均衡

RabbitMQ集群搭建 Linux安装RabbitMQ下载安装基本操作命令开启管理界面及配置 RabbitMQ集群搭建确定rabbitmq安装目录启动第一个节点启动第二个节点停止命令创建集群查看集群集群管理 RabbitMQ镜像集群配置启用HA策略创建一个镜像队列测试镜像队列 负载均衡-HAProxy安装HAProxy…

从计算机底层深入Golang高并发

从计算机底层深入Golang高并发 1.源码流程架构图 2.源码解读 runtime/proc.go下的newpro() func newproc(fn *funcval) {//计算额外参数的地址argpgp : getg()pc : getcallerpc()//s1使用systemstack调用newproc1 systemstack(func() {newg : newproc1(fn, gp, pc)_p_ : getg…