官方关于JSON序列化的文档:JSON and serialization
大致意思是 Flutter 没有类似 Gson 的 JSON 序列化库,那样需要借助反射机制知晓运行时类型,Flutter应用会对多余的代码进行优化,这种优化机制与反射冲突,所以只能借助注解编译生成序列化的代码。Dart内置的 convert 包,有两个函数是用来序列化和反序列化的:
jsonEncode()
jsonDecode()
但是这两个函数是转化 String 和 Map<String, dynamic>,即
String jsonEncode(Map<String, dynamic>)
Map<String, dynamic> jsonDecode(String)
我这里写的函数声明类型跟实际不一样,但是 jsonEncode() 只有传入 Map<String, dynamic> 才能转化成功,基本就是 Map<String, dynamic>对应JSON对象,List<dynamic>对应JSON数组,Dart最开始是携带JS基因的,但是又是强类型语言,Map 类的字面量十分接近JSON,如果要将JSON字符串转成自定义的类,就要编写对应的函数:
//构造函数
ClassName.fromJson(Map<String, dynamic> json)//实例方法
Map<String, dynamic> toJson()
下面是高德web服务API查询天气获取的JSON数据:
{"status": "1","count": "1","info": "OK","infocode": "10000","forecasts": [{"city": "深圳市","adcode": "440300","province": "广东","reporttime": "2022-07-09 16:00:47","casts": [{"date": "2022-07-09","week": "6","dayweather": "多云","nightweather": "多云","daytemp": "33","nighttemp": "27","daywind": "北","nightwind": "北","daypower": "≤3","nightpower": "≤3"},{"date": "2022-07-10","week": "7","dayweather": "多云","nightweather": "多云","daytemp": "33","nighttemp": "27","daywind": "北","nightwind": "北","daypower": "≤3","nightpower": "≤3"},{"date": "2022-07-11","week": "1","dayweather": "晴","nightweather": "晴","daytemp": "33","nighttemp": "27","daywind": "北","nightwind": "北","daypower": "≤3","nightpower": "≤3"},{"date": "2022-07-12","week": "2","dayweather": "晴","nightweather": "晴","daytemp": "33","nighttemp": "27","daywind": "北","nightwind": "北","daypower": "≤3","nightpower": "≤3"}]}]
}

对应的数据类(手动编写JSON序列化代码):

import 'dart:convert';
//手动编写JSON序列化的代码
class Weather {String status = '';String count = '';String info = '';String infocode = '';List<Forecast> forecasts = [];Weather.fromJson(String json) {var result = jsonDecode(json /*, reviver: (key, value) {print('$key=$value ${value.runtimeType}');}*/);// print('result.runtimeType=${result.runtimeType}'); // Map<String, dynamic>status = result['status'];count = result['count'];info = result['info'];infocode = result['infocode'];// print(result['forecasts'].runtimeType);// List<dynamic>forecasts = (result['forecasts'] as List<dynamic>).map((e) => Forecast.fromMap(e as Map<String, dynamic>)).toList();}Map<String, dynamic> toJson() {return {'status': status,'count': count,'info': info,'infocode': infocode,'forecasts': forecasts.map((e) => e.toJson()).toList(),};}
}class Forecast {String city = '';String adcode = '';String province = '';String reporttime = '';List<Cast> casts = [];Forecast.fromMap(Map<String, dynamic> map) {city = map["city"];adcode = map["adcode"];province = map["province"];reporttime = map["reporttime"];casts = (map["casts"] as List<dynamic>).map((e) => Cast.fromMap(e as Map<String, dynamic>)).toList();}Map<String, dynamic> toJson() {return {'city': city,'adcode': adcode,'province': province,'reporttime': reporttime,'casts': casts.map((e) => e.toJson()).toList(),};}
}class Cast {String date = '';String week = '';String dayweather = '';String daytemp = '';String nighttemp = '';String daywind = '';String nightwind = '';String daypower = '';String nightpower = '';Cast.fromMap(Map<String, dynamic> map) {date = map['date'];week = map['week'];dayweather = map['dayweather'];daytemp = map['daytemp'];nighttemp = map['nighttemp'];daywind = map['daywind'];nightwind = map['nightwind'];daypower = map['daypower'];nightpower = map['nightpower'];}Map<String, dynamic> toJson() {return {'date': date,'week': week,'dayweather': dayweather,'daytemp': daytemp,'nighttemp': nighttemp,'daywind': daywind,'nightwind': nightwind,'daypower': daypower,'nightpower': nightpower,};}
}
这里使用的 JSON 数据已经算比较复杂了,如果实际开发中使用更复杂的数据,手动编写就很繁琐了,这时候就要借助工具来生成样板代码,生成样板代码需要在 pubspec.yaml 添加如下依赖:
dependencies:...json_serializable: ^6.3.1dev_dependencies:...build_runner: ^2.1.11

按照官方文档中的示例编写如下的数据类代码(IDE会有红色提示,先忽略,运行本文后面提到的 flutter 指令后会生成缺失的方法),其中两个类的注解带有explicitToJson 参数@JsonSerializable(explicitToJson: true),这样是为了解析嵌套的类:

import 'package:json_annotation/json_annotation.dart';/// This allows the `WeatherX` class to access private members in
/// the generated file. The value for this is *.g.dart, where
/// the star denotes the source file name.
part 'weather_x.g.dart';/// An annotation for the code generator to know that this class needs the
/// JSON serialization logic to be generated.
/// explicitToJson: true 是为了解析嵌套的类
@JsonSerializable(explicitToJson: true)
class WeatherX {String status = '';String count = '';String info = '';String infocode = '';List<ForecastX> forecasts = [];WeatherX(this.status, this.count, this.info, this.infocode, this.forecasts);/// A necessary factory constructor for creating a new WeatherX instance/// from a map. Pass the map to the generated `_$WeatherXFromJson()` constructor./// The constructor is named after the source class, in this case, WeatherX.factory WeatherX.fromJson(Map<String, dynamic> json) =>_$WeatherXFromJson(json);/// `toJson` is the convention for a class to declare support for serialization/// to JSON. The implementation simply calls the private, generated/// helper method `_$WeatherXToJson`.Map<String, dynamic> toJson() => _$WeatherXToJson(this);
}@JsonSerializable(explicitToJson: true)
class ForecastX {String city = '';String adcode = '';String province = '';String reporttime = '';List<CastX> casts = [];ForecastX(this.city, this.adcode, this.province, this.reporttime, this.casts);factory ForecastX.fromJson(Map<String, dynamic> json) =>_$ForecastXFromJson(json);Map<String, dynamic> toJson() => _$ForecastXToJson(this);
}@JsonSerializable()
class CastX {String date = '';String week = '';String dayweather = '';String daytemp = '';String nighttemp = '';String daywind = '';String nightwind = '';String daypower = '';String nightpower = '';CastX(this.date, this.week, this.dayweather, this.daytemp, this.nighttemp,this.daywind, this.nightwind, this.daypower, this.nightpower);factory CastX.fromJson(Map<String, dynamic> json) =>_$CastXFromJson(json);Map<String, dynamic> toJson() => _$CastXToJson(this);
}

然后在工程根目录执行下面的指令:

flutter pub run build_runner build

命令执行成功,就会生成 xxx.g.dart 文件,里面包含了生成的样板代码,之前编写的数据类也不再提示错误,最后就可以使用下面的代码进行JSON序列化和反序列化:

import 'dart:convert';import '../weather_x.dart';// JSON 字符串转 Dart 类实例
WeatherX weatherX = WeatherX.fromJson(jsonDecode(jsonString));// 类实例转 JSON 字符串
String jsonString = jsonEncode(weatherX);

关于 Flutter JSON 序列化相关推荐

  1. 【Flutter】JSON 模型转换 ( JSON 序列化工具 | JSON 手动序列化 | 根据 JSON 编写 Dart 模型类 | 在线自动根据 JSON 转换 Dart 类 )

    文章目录 一.JSON 序列化工具 二.JSON 手动序列化 三.根据 JSON 编写 Dart 模型类 四.在线自动转换 五.相关资源 一.JSON 序列化工具 JSON 格式比较简单的话 , 使用 ...

  2. Flutter中的HTTP网络请求与JSON序列化

    Http 请求 查阅Flutter的相关资料,关于网络请求库,既可以用 dart:io 包中提供的HttpClient,也可以用 flutterchina 推荐的三方封装的请求库 dio 来发起网络请 ...

  3. C#里XML(JSON)序列化时,自动隐藏值为Null的成员的输出

    原文:C#里XML(JSON)序列化时,自动隐藏值为Null的成员的输出 从StackOverflow里找到的答案.发现对最新的Newtownsoft的JSON序列化也同样适用. https://st ...

  4. .NET 自定义Json序列化时间格式

    .NET 自定义Json序列化时间格式 Intro 和 JAVA 项目组对接,他们的接口返回的数据是一个json字符串,里面的时间有的是Unix时间戳,有的是string类型,有的还是空,默认序列化规 ...

  5. C# Json 序列化与反序列化二

    /// <summary>/// 将对象转换为 JSON 字符串/// </summary>/// <typeparam name="T">&l ...

  6. DotNet的JSON序列化与反序列化

    JSON(JavaScript Object Notation)JavaScript对象表示法,它是一种基于文本,独立于语言的轻量级数据交换格式.在现在的通信中,较多的采用JSON数据格式,JSON有 ...

  7. 解决MVC Json序列化的循环引用问题/EF Json序列化循引用问题---Newtonsoft.Json

    1..Net开源Json序列化工具Newtonsoft.Json中提供了解决序列化的循环引用问题: 方式1:指定Json序列化配置为 ReferenceLoopHandling.Ignore 方式2: ...

  8. xml 和 json 序列化忽略字段

    xml 和 json 序列化忽略字段: @JsonIgnore@XmlTransient 转载于:https://www.cnblogs.com/xiluhua/p/9192577.html

  9. 解决Python自带的json序列化工具不能序列化datetime类型数据问题

    解决Python自带的json序列化工具不能序列化datetime类型数据问题 参考文章: (1)解决Python自带的json序列化工具不能序列化datetime类型数据问题 (2)https:// ...

最新文章

  1. 安全事件日志中的登录事件
  2. 解决pip使用异常No module named 'pip'
  3. WinCE6.0中应用程序如何直接访问物理空间
  4. 【iCore4 双核心板_FPGA】例程十六:基于双口RAM的ARM+FPGA数据存取实验
  5. Ranger知识地图
  6. python读取数据文件、并把里面的数据变成x的二维坐标_(数据科学学习手札60)用Python实现WGS84、火星坐标系、百度坐标系、web墨卡托四种坐标相互转换...
  7. linux ACL应用学习
  8. Python基础篇【第六篇】:函数补充
  9. 普通人学python有意义吗-为什么那么多自学Python的后来都放弃了,总结起来就这些原因...
  10. 信号与系统:综述【知识梳理】
  11. 1设计一身高体重测量仪c语言,身高体重测量仪使用经验
  12. 《多媒体在初中数学中的运用研究》课题研究报告
  13. 常见字读音(粤语)---(1)
  14. 进程、线程和协程详解
  15. 麒麟V10系统-系统激活点击按钮无响应
  16. clip-summary
  17. Python爬虫方式抓取免费http代理IP
  18. 读大学,大学四年培养的思维与工作能力,(读研,读博)
  19. 融资融券五月试点 首批入选券商或增至5家
  20. Hive操作——删除表(drop、truncate)

热门文章

  1. Android开发中NDK开发的作用
  2. 使用openssl进行ssl/tls加密传输会话测试
  3. 魅族17手机跟新相机、快充终于完美了
  4. [笔记] 阿里云服务器的相关操作
  5. Java面试题以及答案--Web部分
  6. 转一篇详细的pkt文件的说明文档
  7. 怎么样做好教育培训机构市场推广营销策划
  8. Android Launcher3修改应用图标,隐藏应用图标
  9. 质量检测(c++代码)
  10. 笔记本计算机硬件知识,电脑硬件知识(小白必看)