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 的強大之處。

相關文章
相關標籤/搜索