当前位置: 首页 > news >正文

一篇文章了解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: flutter
  json_annotation: ^4.8.1
  
dev_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最外层的数据结构是数组类型

方案一不支持
方案二支持

相关文章:

  • ​ 轻量应用服务器:亚马逊云科技打造全球领先的云计算解决方案
  • 【深度强化学习】策略梯度方法:REINFORCE、Actor-Critic
  • 前后端传参格式
  • 04-Nacos中负载均衡规则的配置
  • C# 数据的保存和提取(.TXT格式)
  • 外包干了3个月,技术退步明显。。。
  • SSL证书HTTPS保护服务
  • YOLOv8使用自定义改进后的模型同时《加载官方预训练权重》教程,附代码
  • C_1练习题答案
  • 算法通关第十九关-青铜挑战理解动态规划
  • Maven项目引入本地jar
  • 使用drawio绘制依赖关系图
  • 智能优化算法应用:基于和声算法3D无线传感器网络(WSN)覆盖优化 - 附代码
  • vue整个页面可以拖拽导入文件
  • 在windows系统搭建LVGL模拟器(codeblock工程)
  • [论文笔记] 大模型主流Benchmark测试集介绍
  • 【第二章】docker +Jenkins+git+allure+python3安装
  • 『K8S 入门』二:深入 Pod
  • 云原生之深入解析如何在Kubernetes中快速启用Cgroup V2支持
  • Docker与K8s的区别
  • 体验中国传统文化、采购非遗文创,波兰游客走进上海市群艺馆
  • 外交部发言人就印巴局势升级答记者问
  • 游戏论|暴君无道,吊民伐罪——《苏丹的游戏》中的政治
  • 报告:4月份新增发行的1763亿元专项债中,投向房地产相关领域约717亿元
  • 王受文已任全国工商联党组成员
  • 开局良好,我国第一季度广告业务收入保持较快增速