引言
在传统Web开发领域我们通过ajax请求接收到后端发来的数据时,浏览器都已经帮我们完成了json
的序列化,而在Flutter
显然是不支持直接显示后端接收到的请求的,如此我们就需要对请求接收到的数据进行序列化,转变成为我们能看懂的东西。这里我主要介绍JSON 和序列化数据 - Flutter 中文文档 - Flutter 中文开发者网站 - Flutter中的三种序列化方式。
-
直接使用内联序列化JSON数据(这种方式很方便,但是在代码运行前你都无法知道你取的类型是否正确,导致代码很容易出错)
内联序列化JSON数据
实现方法很简单,主要依靠Flutter
内置的json.decode()
函数来对接收到后端的数据进行解码。
先说结论,主要用的就是json.decode(value.toString());
,就是将获取到的数据转为字符串后进行json
解码。
//发送请求类 这里使用的是dio来进行发请求 就简易的实现发送get请求 import 'package:dio/dio.dart'; class Request{ // 配置实例 static final BaseOptions _options = BaseOptions( // baseUrl配置要发请求的地址 baseUrl: 'http://127.0.0.1:3000/', //连接超时时间 connectTimeout: 5000, //接收超时时间 receiveTimeout: 5000); // 创建Dio实例 static Dio _dio = Dio(_options); Future get(String path, {Map<String, dynamic>? params}) { if (params != null) { return _dio.get(path, queryParameters: params); } return _dio.get(path); } }
有了发送请求类,接下来就是调用像后端发送请求。
//这里是发送请求获取具体数据的类 import 'package:imapp/http/request.dart'; class ContactsModel { //创建请求实例 Request http = Request(); //根据传入的userId来向后端发送请求 Future getContactsInfo(int userId) { return http.get('/userContacts', params: {"userId": userId}); } }
经过上面一系列的操作后,就是具体视图层的操作。这里是主要进行序列化的地方
//获取联系人模型,就是将上方的类进行实例化 ContactsModel contactsModel = new ContactsModel(); //用来存放获取的用户数据 late Map<String, dynamic> contactsResult; // 获取联系人 await contactsModel .getContactsInfo(id) .then((value) { print('------------联系人数据----------'); //主要序列化的方式 contactsResult = json.decode(value.toString()); if (contactsResult['code'] == 200) { //这就获取到了后端的数据了 print(contactsResult['data']); } });
使用上方这种方法,想获取内部数据就只能用map['name']
这种形式来读取,就很难判断类型,因此需要更好的方法。
在模型类中序列化 JSON 数据
在上方代码中新建一个模型类来解决难以判断类型的方法。代码如下:
//模型类 这里直接拷贝文档的代码了,想了解更多可以去阅读官方文档(文档很清晰!!!) 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, }; }
接下来在上方获取联系人的时候使用这个模型类
ContactsModel contactsModel = new ContactsModel(); //用来存放获取的用户数据 late Map<String, dynamic> contactsResult; // 获取联系人 await contactsModel .getContactsInfo(id) .then((value) { print('------------联系人数据----------'); //主要序列化的方式 contactsResult = json.decode(value.toString()); if (contactsResult['code'] == 200) { //这就获取到了后端的数据了 print(contactsResult['data']); //主要操作在这!!!!! var user = User.fromJson(contactsResult['data']) //就可以直接使用user.email来获取到数据了 print(user.email);//打印email } });
虽然这种方法解决了无法判断类型的问题,但仍然不是最优的方法,有没有一种方法可以直接根据我们提供的参数自动生成json
序列化格式呢?当然是有的,官方就推荐了使用json_serializable
。
具体如下。
使用代码生成库序列化 JSON 数据
在此之前,需要安装依赖:
#这些都需要安装 dependencies: # 生成依赖 json_annotation: <latest_version> dev_dependencies: # 开发依赖 build_runner: <latest_version> json_serializable: <latest_version>
在项目根目录下运行flutter pub get 包名
或者直接在pubspec.yaml
进行安装。
安装完成后,以上方当时的User
模型类来作为例子。
import 'package:json_annotation/json_annotation.dart'; part 'user.g.dart';//这部分在使用flutter pub run build_runner watch来进行监听后会自动根据类型来生成,所以要保证前后端的参数名要一致 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); }
这样就会和原先达到相同的效果,但是以更加灵活的方式来实现,调用的方法还是与第二种方法是相同的。