Flutter学习JSON 和序列化数据
1. 概述
Dart中没有类似于GSON/Jackson这种在Java编程中普遍使用的JSON处理工具,因为这样的库需要使用运行时进行 反射,这在 Flutter 中是被禁用的。
Dart中一般有两种JSON序列化和反序列化方式
- 手动序列化数据
- 利用代码生成进行自动序列化数据
一般,较小的项目使用手动序列化数据,中大型项目使用代码生成。
无论哪种方式,都需要在实体类中添加转换方法,其中从JSON转换为实体类的方法被定义为实体类的构造器,且方法名约定俗成地命名为fromJson
;从实体类转换为JSON则是普通的方法,方法名常定义为toJsoon
。
下面的例子取自Flutter文档,该例子使用一个包含String name
和 String email
的User
类及如下JSON字符串进行说明:
{
"name": "John Smith",
"email": "john@example.com"
}
2. 手动序列化数据
User类在user.dart
文件中定义如下:
class User {
final String name;
final String email;
User(this.name, this.email);
User.fromJson(Map<String, dynamic> json)
: name = json['name'],
email = json['email'];
Map<String, dynamic> toJson() => {
'name': name,
'email': email,
};
}
3. 利用代码生成进行自动序列化数据
尽管有其它库可以使用,但是这里使用json_serializable
,一个自动化源代码生成器来用来生成 JSON 序列化数据模板。
3.1 添加json_serializable依赖
在dependencies
中添加json_annotation
和build_runner
,在dev_dependencies
中添加json_serializable
,截止目前都是最新版本(可在此查看最新依赖版本)。
我的pubspec.yaml依赖部分如下:
environment:
sdk: '>=2.19.0 <3.0.0'
dependencies:
json_annotation: ^4.8.0
build_runner: ^2.3.3
dev_dependencies:
json_serializable: ^6.6.1
3.2 配置实体类文件
json_serializable
会根据定义的实体类自动生成转换的代码,这部分代码单独放在一个名称为当前实体类文件后缀名为.g.dart
的文件中(*.g.dart
文件,*
代表实体类文件名)。转换的方法名以_$
开头,表示私有并自动生成,fromJson
对应的方法名为_$BeanFromJson
,toJson
对应的方法名为_$BeanToJson
,其中Bean
代表实体类名称。*.g.dart
文件会被作为实体类文件的一部分,被引用到实体类文件中用于实现fromJson
和toJson
方法,为此按如下步骤配置实体类:
- 在
user.dart
文件中重新定义User
类 - 以
part
的方式引入自动生成的文件user.g.dart
,即part 'user.g.dart';
; - 在类上添加
@JsonSerializable
注解(为此需要import json_annotation包),且为了以正常格式输出嵌套类的数据,将注解的explicitToJson
设置为true
; - 定义
fromJson
工厂构造器和toJson
方法,直接使用胖箭头调用自动生成的转换方法,方法名为_$UserFromJson
和_$UserToJson
与自动生成的方法名一致。
import 'package:json_annotation/json_annotation.dart';
part 'user.g.dart';
@JsonSerializable(explicitToJson: true)
class User {
final String name;
final String email;
User(this.name, this.email);
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}
3.3 运行代码生成工具
配置好实体类文件后还不能直接使用,此时user.dart
文件中的代码还会报错,因为这时候还没有生成user.g.dart
文件。json_serializable
提供了代码生成器来自动生成该文件,根据 json_serializable文档:
- 如果是Dart环境,可以在项目根目录下运行
dart run build_runner build
命令 - 如果是Flutter环境,则在项目根目录下运行
flutter pub run build_runner build
命令
我的是Flutter环境,运行flutter pub run build_runner build
命令后会在user.dart
同目录下生成一个user.g.dart
文件,文件内容如下:
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'user.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
User _$UserFromJson(Map<String, dynamic> json) => User(
json['name'] as String,
json['email'] as String,
);
Map<String, dynamic> _$UserToJson(User instance) => <String, dynamic>{
'name': instance.name,
'email': instance.email,
};
此时,user.dart
中已经不会报错了。
上述代码生成器命令只会运行一次,如果我们修改了user.dart
中的代码,则user.g.dart
中的内容可能也需要随着修改,这样就需要重新运行一次命令,很不“智能”。为了实现“实时”监控文件变化从而自动重新生成.g.dart
文件,json_serializable
提供了监控命令:
flutter pub run build_runner watch
在项目根目录运行该命令后程序会持续监听文件变化,并且会在需要的时候自动构建必要的文件(但是可能会有延迟)。
4. 使用JSON
dart:convert
包可以转换JSON数据:
- 将字符串转换为JSON对象:jsonDecode(String source)
- 将对象转换为字符串:jsonEncode(Object object)
测试代码如下:
import 'dart:convert';
void main() {
// 假定有如下JSON格式的字符串
String jsonString = """
{
"name": "John Smith",
"email": "john@example.com"
}
""";
// 首先将该字符串转换为JSON对象
Map<String, dynamic> json = jsonDecode(jsonString);
// 然后用JSON对象构造Dart对象
User user = User.fromJson(json);
// 反过来,再将Dart对象转为JSON对象
Map<String, dynamic> json1 = user.toJson();
// 当然也可以将对象序列化字符串
String jsonString = jsonEncode(user);
print(jsonString);
}
参考
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgcacaa
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01