Http 请求
查阅Flutter的相关资料,关于网络请求库,既可以用 dart:io 包中提供的HttpClient,也可以用 flutterchina 推荐的三方封装的请求库 dio 来发起网络请求,还可以用Flutter 官方介绍的 http。
下分别介绍这几种发起网络请求的库:
1.dart自带的HttpClient
查看详情 https://flutterchina.club/networking/
HttpClient 位于dart:io,所以要创建一个HttpClient , 我们需要添加一个导入:
import 'dart:io';
var httpClient = new HttpClient();
该 client 支持常用的HTTP操作, such as GET, POST, PUT, DELETE.
示例get:
get() async {
var httpClient = new HttpClient();
var uri = new Uri.http(
'example.com', '/path1/path2', {
'param1': '42', 'param2': 'foo'});
// httpClient.post(host, port, path)
var request = await httpClient.getUrl(uri);
var response = await request.close();
var responseBody = await response.transform(utf8.decoder).join();
print(responseBody);
}
2.Flutter 官方介绍的http
查看详情 https://flutter.dev/docs/cookbook/networking/fetch-data
dependencies:
http: <latest_version>
发起请求
Future<Post> fetchPost() async {
final response =
await http.get('https://jsonplaceholder.typicode.com/posts/1');
if (response.statusCode == 200) {
// If server returns an OK response, parse the JSON
return Post.fromJson(json.decode(response.body));
} else {
// If that response was not OK, throw an error.
throw Exception('Failed to load post');
}
}
3.flutterchina 推荐的三方库dio
查看详情 https://github.com/flutterchina/dio/blob/master/README-ZH.md
添加依赖
dependencies:
dio: ^2.1.x // 请使用pub上2.1分支的最新版本
简单示例
import 'package:dio/dio.dart';
void getHttp() async {
try {
Response response = await Dio().get("http://www.baidu.com");
print(response);
} catch (e) {
print(e);
}
}
JSON和序列化
针对服务端返回的数据,先将其进行反序列化,然后使用对象是比较正规的方式,将json 反序列化成对象,有两种方式:手动解析json或者使用三方序列化工具 。
注意:这里服务端返回的数据首先要转换成json 格式,如果使用dio 发起的请求,那么默认的返回类型就已经是json, 如果其他方式发起的请求 返回可能需要去转格式。
手动解析json
Map<String, dynamic> user = json.decode(json);
print('Howdy, ${user['name']}!');
print('We sent the verification link to ${user['email']}.');
在模型类中序列化JSON
我们可以通过引入一个简单的模型类(model class)来解决前面提到的问题,我们称之为User。在User类内部,我们有:
一个User.fromJson 构造函数, 用于从一个map构造出一个 User实例
一个toJson 方法, 将 User 实例转化为一个map.
这样,调用代码现在可以具有类型安全、自动补全字段(name和email)以及编译时异常。如果我们将拼写错误或字段视为int类型而不是String, 那么我们的应用程序就不会通过编译,而不是在运行时崩溃。
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,
};
}
现在,序列化逻辑移到了模型本身内部。采用这种新方法,我们可以非常容易地反序列化user。
Map userMap = JSON.decode(json);
var user = new User.fromJson(userMap);
print('Howdy, ${user.name}!');
print('We sent the verification link to ${user.email}.');
要序列化一个user,我们只是将该User对象传递给该JSON.encode方法。我们不需要手动调用toJson这个方法,因为JSON.encode已经为我们做了。
String json = JSON.encode(user);
json_serializable序列化JSON
详情查看 https://github.com/dart-lang/json_serializable/tree/master/example
pubspec.yaml 添加依赖
dependencies:
# Your other regular dependencies here
json_annotation: ^2.0.0
dev_dependencies:
# Your other dev_dependencies here
build_runner: ^1.0.0
json_serializable: ^2.0.0
在您的项目根文件夹中运行 flutter packages get (或者在编辑器中点击 “Packages Get”) 以在项目中使用这些新的依赖项.
以json_serializable的方式创建model类
让我们看看如何将我们的User类转换为一个json_serializable。为了简单起见,我们使用前面示例中的简化JSON model。
user.dart
import 'package:json_annotation/json_annotation.dart';
// user.g.dart 将在我们运行生成命令后自动生成
part 'user.g.dart';
///这个标注是告诉生成器,这个类是需要生成Model类的
@JsonSerializable()
class User{
User(this.name, this.email);
String name;
String email;
//不同的类使用不同的mixin即可
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}
有了这个设置,源码生成器将生成用于序列化name和email字段的JSON代码。
如果需要,自定义命名策略也很容易。例如,如果我们正在使用的API返回带有_snake_case_的对象,但我们想在我们的模型中使用_lowerCamelCase_, 那么我们可以使用@JsonKey标注:
/// Tell json_serializable that "registration_date_millis" should be
/// mapped to this property.
@JsonKey(name: 'registration_date_millis')
final int registrationDateMillis;
运行代码生成程序
json_serializable第一次创建类时,您会看到与下图类似的错误。
这些错误是完全正常的,这是因为model类的生成代码还不存在。为了解决这个问题,我们必须运行代码生成器来为我们生成序列化模板。
有两种运行代码生成器的方法:
一次性生成
通过在我们的项目根目录下运行flutter packages pub run build_runner build,我们可以在需要时为我们的model生成json序列化代码。
持续生成
使用_watcher_可以使我们的源代码生成的过程更加方便。它会监视我们项目中文件的变化,并在需要时自动构建必要的文件。我们可以通过flutter packages pub run
build_runner watch在项目根目录下运行来启动_watcher_。
只需启动一次观察器,然后并让它在后台运行,这是安全的。
使用json_serializable模型
Map userMap = JSON.decode(json);
var user = new User.fromJson(userMap);
序列化也一样。调用API与之前相同。
String json = JSON.encode(user);
有了json_serializable,我们可以在User类上忘记任何手动的JSON序列化 。源代码生成器创建一个名为user.g.dart的文件,它具有所有必需的序列化逻辑。
还有一个网页版在线将json-> dart
https://javiercbk.github.io/json_to_dart/
这里有我学习Flutter过程中的一个Demo,会持续更新Demo的内容,对Flutter 有兴趣的朋友可以一起学习。
https://github.com/CodingForAndroid/flutter_new
欢迎爱学习的小伙伴加群一起进步:230274309 今天的文章Flutter中的HTTP网络请求与JSON序列化分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/30207.html