一篇文章了解Flutter Json系列化和反序列化
2023-12-14 21:45:10
目录
一. 使用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_annotation
、build_runner
、json_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个要素:
- 导入
json_annotation
库注解,用于标识JSON字段和生成代码的相关信息。使用@JsonSerializable()
注解类,用@JsonKey(name: 'xx')
注解字段,xx必须与JSON字段一一对应part 'xx.g.dart';
xx是当前文件名称,缺失这个配置或者配置错误,都会导致生成文件出错;_$XXFromJson
和_$XXToJson
是通过build_runner
自动生成的代码,用于序列化和反序列化JSON数据。
3. 使用命令行生成JSON序列化和反序列化的代码:
flutter packages pub run build_runner build
这个命令会为你的数据模型类生成user.g.dart
文件,其中包含了_$XXFromJson
和_$XXToJson
方法的实现。
XX.g.dart
默认会生成在模型类的同级目录。
- 如果有其他.g文件存在影响,可用这个命令
flutter packages pub run build_runner build --delete-conflicting-outputs
- 如果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);
三、 两种方案对比
相同点:
- 将
Map
对象转化成JSON字符串以及将Map对象转化成JSON字符串都是依赖convert
; - JSON字符串和数据模型之间转化都需要借助
Map
对象;
不同点:
- 处理数据模型字段变更场景,方案二修改代码较少,出错的概率更低:
方案一需要添加或者修改字段并且手动修改
fromJson
和toJson
方法;
方案二需要添加或者修改字段,添加相关注解,并重新使用命令行生成JSON序列化和反序列化的代码;
- Json最外层的数据结构是数组类型
方案一不支持
方案二支持
文章来源:https://blog.csdn.net/qq_26585943/article/details/134971588
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!