flutter学习-day18-网络请求
📚 目录
- 通过HttpClient发起HTTP请求
- 使用dio发起请求
2. 安装dio库
2. 发起请求
2. 完整例子 - JSON转DartModel类
3. json转dart
3. json转dartmodel
3. 自动生成model类
本文学习和引用自《Flutter实战·第二版》:作者:杜文
1. 通过HttpClient发起HTTP请求
Dart IO库中提供了用于发起Http请求的一些类,我们可以直接使用HttpClient来发起请求。
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
/// 定义
class HomePage extends StatefulWidget {
const HomePage({super.key});
State<HomePage> createState() => HomePageState();
}
/// 实现
class HomePageState extends State<HomePage> {
// 请求地址
final String serverPath = 'https://xxxxxxxxx';
String str = '';
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter Home'),
),
body: Container(
alignment: Alignment.center,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Text(str, style: const TextStyle(fontSize: 24.0),)
],
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
handleGetData();
},
child: const Text('请求'),
),);
}
handleGetData() async {
String path = '$serverPath/get/message';
try {
/// 创建一个HttpClient
HttpClient httpClient = HttpClient();
/// 打开http连接
HttpClientRequest requestObject =
await httpClient.getUrl(Uri.parse(path));
/// 设置请求头
requestObject.headers.add('Content-Type', 'application/json');
/// 等待连接服务器(会将请求信息发送给服务器)
HttpClientResponse response = await requestObject.close();
/// 读取响应内容
str = await response.transform(const Utf8Decoder()).join();
/// 输出响应头
debugPrint('响应头:${response.headers.toString()}');
} catch (error) {
debugPrint(error.toString());
}
}
}
2. 使用dio发起请求
直接使用HttpClient发起网络请求是比较麻烦的,很多事情得我们手动处理,如果再涉及到文件上传/下载、Cookie管理等就会非常繁琐。而第三方http请求库,用它们来发起http请求将会简单的多,比如目前人气较高的dio库。
2-1. 安装dio库
尽量使用pub.dev上的最新版本。
dependencies:
dio: ^x.x.x
2-2. 发起请求
一个dio实例可以发起多个http请求,一般来说,APP只有一个http数据源时,dio应该使用单例模式。
- 引入并创建实例
import 'package:dio/dio.dart';
Dio dio = Dio();
Response response;
- 发起get请求
response = await dio.get("/test?id=12&name=test");
// 或者
response = await dio.get("/test", queryParameters:{"id":12,"name":"test"})
debugPrint(response.data.toString());
- 发起post请求
response = await dio.post("/test",data:{"id":12,"name":"test"})
- 同时发起多个请求
response = await Future.wait([dio.post("/info"), dio.get("/token")]);
- 下载文件
response = await dio.download("https://www.google.com/", savePath);
- 发送FormData
FormData formData = FormData.from({
"name": "wendux",
"age": 25,
});
response = await dio.post("/info", data: formData)
- 设置代理
(dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (client) {
// 设置代理
client.findProxy = (uri) {
return "PROXY 192.168.1.2:8888";
};
// 校验证书
httpClient.badCertificateCallback = (X509Certificate cert, String host, int port){
if(cert.pem == PEM){
// 证书一致,则允许发送数据
return true;
}
return false;
};
};
2-3. 完整例子
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
/// 定义
class HomePage extends StatefulWidget {
const HomePage({super.key});
State<HomePage> createState() => HomePageState();
}
/// 实现
class HomePageState extends State<HomePage> {
Dio myDio = Dio();
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter Home'),
),
body: Container(
alignment: Alignment.center,
child: FutureBuilder(
future:
myDio.get("https://api.github.com/orgs/flutterchina/repos"),
builder: (BuildContext context, AsyncSnapshot snapshot) {
//请求完成
if (snapshot.connectionState == ConnectionState.done) {
Response response = snapshot.data;
//发生错误
if (snapshot.hasError) {
return Text(snapshot.error.toString());
}
//请求成功,通过项目信息构建用于显示项目名称的ListView
return ListView(
children: response.data
.map<Widget>(
(e) => ListTile(title: Text(e["full_name"])))
.toList(),
);
}
//请求未完成时弹出loading
return const CircularProgressIndicator();
},
)));
}
}
3. JSON转DartModel类
后台接口往往会返回一些结构化数据,如 JSON、XML 等,如之前我们请求 Github API 的示例,它返回的数据就是 JSON 格式的字符串,为了方便我们在代码中操作 JSON,我们先将 JSON 格式的字符串转为 Dart 对象,这个可以通过 dart:convert 中内置的 JSON 解码器json.decode()来实现,该方法可以根据 JSON 字符串具体内容将其转为 List 或 Map,这样我们就可以通过他们来查找所需的值。
3-1. JSON转Dart
将 JSON 格式的字符串转为 Dart 对象,可以使用 dart:convert 中的 JSON 解码器 json.decode() 来实现,该方法可以根据 JSON 字符串具体内容将其转为 List 或 Map,这样我们就可以通过他们来查找所需的值。
// 一个JSON格式的用户列表字符串
String jsonStr='[{"name":"Jack"},{"name":"Rose"}]';`
// 将JSON字符串转为Dart对象(此处是List)
List items=json.decode(jsonStr);
// 输出第一个用户的姓名
print(items[0]["name"]);
3-2. JSON转DartModel
但是,由于json.decode()仅返回一个Map<String, dynamic>,这意味着直到运行时我们才知道值的类型。 通过这种方法,我们失去了大部分静态类型语言特性:类型安全、自动补全和最重要的编译时异常。解决方法即“Json Model化”,具体做法就是,通过预定义一些与 Json 结构对应的 Model 类,然后在请求到数据后再动态根据数据创建出 Model 类的实例。这样一来,在开发阶段我们使用的是 Model 类的实例,而不再是 Map/List,这样访问内部属性时就不会发生拼写错误。如下,是一个简单的模型类:
/// 定义
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() =>
<String, dynamic>{
'name': name,
'email': email,
};
}
/// 使用
Map userMap = json.decode(json);
var user = User.fromJson(userMap);
print('名字:${user.name}');
print('邮箱:${user.email}');
3-3. 自动生成Model类
在 Android Studio 中安装 JsonToDart 插件,打开 Preferences(Mac)或者 Setting(Window),选择 Plugins,搜索 JsonToDart。点击 Install 安装,安装完成后重启。这个时候选定目录,点击右键,选择 New->Json to Dart,选中 Json To Dart 后,弹出页面输入要转换的json数据,点击完成,就会生成对应的模型文件了。
本次分享就到这儿啦,我是鹏多多,如果您看了觉得有帮助,欢迎评论,关注,点赞,转发,我们下次见~
往期文章
- Vue2全家桶+Element搭建的PC端在线音乐网站
- vue3+element-plus配置cdn
- 助你上手Vue3全家桶之Vue3教程
- 助你上手Vue3全家桶之VueX4教程
- 助你上手Vue3全家桶之Vue-Router4教程
- 超详细!Vue的九种通信方式
- 超详细!Vuex手把手教程
- 使用nvm管理node.js版本以及更换npm淘宝镜像源
- vue中利用.env文件存储全局环境变量,以及配置vue启动和打包命令
- 超详细!Vue-Router手把手教程
个人主页
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!