写点什么

Dio —— Flutter 网络请求之王者

作者:岛上码农
  • 2022 年 4 月 16 日
  • 本文字数:2389 字

    阅读完需:约 8 分钟

Dio —— Flutter 网络请求之王者

在 Flutter 中,要说网络请求插件,不得不提 dio,而且这是国人开发的开源插件,在 pub 上好评率达到 99%,GitHub 也收获了近万 star。借用官方文档的一句话描述:dio 是一个强大的 Dart Http 请求库,支持 Restful API、FormData、拦截器、请求取消、Cookie 管理、文件上传/下载、超时、自定义适配器等...可以说是覆盖了所有涉及到的网络请求。

前期准备

要开始网络请求部分了,验证接口请求是个麻烦事, 单纯的测试 CRUD 请求倒还好,可以使用 JsonPlaceholder这样的工具来完成(国内访问有点慢)。如果要弄一个完整的 App,则需要有后端搭配,要是不懂后端就麻烦了,只能实用 Mock 工具了。作为要成为全栈的同学来说,怎么能 Mock 就算了呢,不会写,咱还不会淘啊!GitHub 走一圈,找到了一个基于 Express.js 框架的 api 源码,是一个老外写的,看了看,发现也不太难懂, 生搬硬套改呗!



后台源码我已经上传了,大家可以自行看,如果不想看的,直接按文档配置好环境, 在目录下执行一下命令 node index.js 就可以启动本地服务,监听的 api 地址在:http://localhost:3900/api/。想自己改的,需要具备以下知识(努力学吧,少年!)


  • MongoDB:后台数据库使用的是 MongoDB,采用 mongoose 实现的 MongoDB 访问,基本的 MongoDB 操作要会,可以参考本人关于 MongoDB 的文章MongoDB 不专业指北

  • Javascript:JS 不会,肯定玩不转,不过 Dart 和 JS 很像,学起来不会怎么费劲。

你好,dio

dio 这个名字就很中国化(按拼音读你就懂了,也可能是我想歪了,原意可能是 Dart IO 的缩写吧)。dio 目前最新的版本已经是 4.0.0 了。先来看基本的 get,post,put,patch,delete 请求的写法。get 请求


Response response;var dio = Dio();response = await dio.get('/test?id=12&name=wendu');print(response.data.toString());// 也可以实用 query 参数的方式请求response = await dio.get('/test', queryParameters: {'id': 12, 'name': 'wendu'});print(response.data.toString());
复制代码


post 请求


response = await dio.post('/test', data: {'id': 12, 'name': 'wendu'});
复制代码


patch、put 请求


var result = await Dio().patch('/test/12', data: data);var result = await Dio().put('/test/12', data: data);
复制代码


delete 请求


var result = await Dio().delete('/test/12');
复制代码


使用起来也比较简单,返回的 result 会包括的 http 请求的状态码,信息,header 和响应数据,其中响应数据在 data 属性里面。

小试牛刀

之前介绍了Flutter如何构建图文列表,之前的数据是我们的 Mock 数据,现在修改成从网络上获取,接口已经准备好了,为:http://localhost:3900/api/dynamics,支持传入分页参数进行分页。为了简单起见,只返回了分页数据,没有返回分页信息。_注:可以在后台工程目录下运行 _**_node seed.js_**_ 生成数据库数据。_


在 pubspec.yaml 中加入 dio 的依赖:


dio: ^4.0.0
复制代码


实体类准备为了避免实用 Map 的 key 下标访问,我们准备一个实体类 DynamicEntity,将 Map 数据转换为实体对象。


class DynamicEntity {  String _title;  String _imageUrl;  int _viewCount;  String _id;
get title => _title; get imageUrl => _imageUrl; get viewCount => _viewCount; get id => _id;
static DynamicEntity fromJson(Map<String, dynamic> json) { DynamicEntity newEntity = DynamicEntity(); newEntity._id = json['_id']; newEntity._title = json['title']; newEntity._imageUrl = json['imageUrl']; newEntity._viewCount = json['viewCount'];
return newEntity; }}
复制代码


接口请求类新建一个接口请求类DynamicService,将动态涉及到的网络请求统一放入该类调用,里面的方法均定义为静态方法,避免需要实例化对象来请求,目前我们只验证列表接口,这里也没有做错误和异常处理。


import 'package:dio/dio.dart';
class DynamicService { static String host = 'http://localhost:3900/api/'; static Future list(page, pageSize) async { var result = await Dio().get( host + 'dynamics', queryParameters: {'page': page, 'pageSize': pageSize}, );
return result; }}
复制代码

修改原有 Mock 数据为网络请求

我们之前的 Mock 数据就是仿照 API 接口做的,因此换起来很方便,可以对比一下代码:


//使用Mock数据void _requestNewItems() async {    List<Map<String, dynamic>> _jsonItems =        await DynamicMockData.list(_currentPage, PAGE_SIZE);    List<DynamicEntity> _newItems =        _jsonItems.map((json) => DynamicEntity.fromJson(json)).toList();    this.setState(() {      if (_currentPage > 1) {        _listItems += _newItems;      } else {        _listItems = _newItems;      }    });  }
// 更换为网络请求后void _requestNewItems() async { var response = await DynamicService.list(_currentPage, PAGE_SIZE); List<dynamic> _jsonItems = response.data; List<DynamicEntity> _newItems = _jsonItems.map((json) => DynamicEntity.fromJson(json)).toList(); this.setState(() { if (_currentPage > 1) { _listItems += _newItems; } else { _listItems = _newItems; } }); }
复制代码


实际开发过程中,可以让 Mock 数据类和真实的接口类实现相同的接口,这样就可以只需要替换接口的实现类就可以了,也就是常说的面向接口编程

跑起来

修改完成后,直接运行代码,效果如下所示,可以看到 id 已经发生了改变。


总结

本篇简单介绍了 dio ,以及使用 get 请求完成了列表数据的获取,窥一貌而知全部,可以看到 dio 的简单易用。后续将陆续介绍其他的请求以及更为高级的用法,来见证 dio 的强大之处。



发布于: 刚刚阅读数: 2
用户头像

岛上码农

关注

用代码连接孤岛,公众号@岛上码农 2022.03.03 加入

从南漂到北,从北漂到南的业余码农

评论

发布
暂无评论
Dio —— Flutter 网络请求之王者_flutter_岛上码农_InfoQ写作平台