Flutter入门与实战(二十二):初次见面,网络请求王者之dio

这是我参与更文挑战的第30天,活动详情查看: 更文挑战node

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

前期准备

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

生搬硬套

后台源码我已经上传了,你们能够自行看,若是不想看的,直接按文档配置好环境, 在目录下执行一下命令 node index.js就能够启动本地服务,监听的 api 地址在:http://localhost:3900/api/。想本身改的,须要具有如下知识(努力学吧,少年!)express

  • MongoDB:后台数据库使用的是 MongoDB,采用 mongoose 实现的 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 请求json

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请求api

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

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

小试牛刀

以前介绍了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 已经发生了改变。 屏幕录制2021-06-30 下午9.44.44.gif

总结

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

相关文章
相关标签/搜索