Flutter網絡請求庫Dio的封裝(單例、動態baseUrl、攔截器)


https://www.jianshu.com/p/5ead0cf96642

 

封裝網絡請求的幾個好處:
1、便於統一配置請求參數,如header,公共參數,加密規則等
2、方便調試,日志打印
3、優化代碼性能,避免到處濫new對象,構建全局單例
4、簡化請求步驟,只暴露需要的響應數據,而對錯誤的響應統一回調
5、對接口數據的基類封裝,簡化解析流程
效果示例:https://github.com/sundaysmeSwift/FlutterNetDio.git


 
image.png

HttpManager的定義

構造全局單例,配置請求參數,配置通用的GET\POST,支持baseUrl的切換

class HttpManager { static HttpManager _instance = HttpManager._internal(); Dio _dio; factory HttpManager() => _instance; ///通用全局單例,第一次使用時初始化 HttpManager._internal({String baseUrl}) { if (null == _dio) { _dio = new Dio(new BaseOptions( baseUrl: Address.BASE_URL_RELEASE, connectTimeout: 15000)); _dio.interceptors.add(new LogsInterceptors()); _dio.interceptors.add(new ResponseInterceptors()); } } static HttpManager getInstance({String baseUrl}) { if (baseUrl == null) { return _instance._normal(); } else { return _instance._baseUrl(baseUrl); } } //用於指定特定域名,比如cdn和kline首次的http請求 HttpManager _baseUrl(String baseUrl) { if (_dio != null) { _dio.options.baseUrl = baseUrl; } return this; } //一般請求,默認域名 HttpManager _normal() { if (_dio != null) { if (_dio.options.baseUrl != Address.BASE_URL_RELEASE) { _dio.options.baseUrl = Address.BASE_URL_RELEASE; } } return this; } ///通用的GET請求 get(url, params, {noTip = false}) async { Response response; try { response = await _dio.get(url, queryParameters: params); } on DioError catch (e) { return resultError(e); } if (response.data is DioError) { return resultError(response.data['code']); } return response.data; } ///通用的POST請求 post(url, params, {noTip = false}) async { Response response; try { response = await _dio.post(url, data: params); } on DioError catch (e) { return resultError(e); } if (response.data is DioError) { return resultError(response.data['code']); } return response.data; } } 

日志攔截器

打印請求參數和返回參數

import 'package:dio/dio.dart'; class LogsInterceptors extends InterceptorsWrapper { 

響應攔截器

過濾正確的響應數據,對數據進行初步封裝

import 'package:dio/dio.dart'; import 'package:exchange_flutter/common/net/code.dart'; import 'package:flutter/material.dart'; import '../result_data.dart'; class ResponseInterceptors extends InterceptorsWrapper { @override onResponse(Response response) { RequestOptions option = response.request; try { if (option.contentType != null && option.contentType.primaryType == "text") { return new ResultData(response.data, true, Code.SUCCESS); } ///一般只需要處理200的情況,300、400、500保留錯誤信息 if (response.statusCode == 200 || response.statusCode == 201) { int code = response.data["code"]; if (code == 0) { return new ResultData(response.data, true, Code.SUCCESS, headers: response.headers); } else if (code == 100006 || code == 100007) { } else { Fluttertoast.showToast(msg: response.data["msg"]); return new ResultData(response.data, false, Code.SUCCESS, headers: response.headers); } } } catch (e) { print(e.toString() + option.path); return new ResultData(response.data, false, response.statusCode, headers: response.headers); } return new ResultData(response.data, false, response.statusCode, headers: response.headers); } } 

響應基類

默認200的情況isSuccess為true,響應為response.data,賦值給data

class ResultData { var data; bool isSuccess; int code; var headers; ResultData(this.data, this.isSuccess, this.code, {this.headers}); } 

Api的封裝

請求的集中管理

class Api { ///示例請求 static request(String param) { var params = DataHelper.getBaseMap(); params['param'] = param; return HttpManager.getInstance().get(Address.TEST_API, params); } } 

公共參數和加密等

class DataHelper{ static SplayTreeMap getBaseMap() { var map = new SplayTreeMap<String, dynamic>(); map["platform"] = AppConstants.PLATFORM; map["system"] = AppConstants.SYSTEM; map["channel"] = AppConstants.CHANNEL; map["time"] = new DateTime.now().millisecondsSinceEpoch.toString(); return map; } static string2MD5(String data) { var content = new Utf8Encoder().convert(data); var digest = md5.convert(content); return hex.encode(digest.bytes); } } 

地址的配置

方便地址管理

class Address { static const String TEST_API = "test_api"; } 

示例請求

dart的json解析推薦使用json_serializable,其他的有些坑,慎用

void request() async { ResultData res = await Api.request("param"); if (res.isSuccess) { //拿到res.data就可以進行Json解析了,這里一般用來構造實體類 TestBean bean = TestBean.fromMap(res.data); }else{ //處理錯誤 } } 

Demo地址 https://github.com/po1arbear/Flutter-Net.git



作者:刺客的幻影
鏈接:https://www.jianshu.com/p/5ead0cf96642
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM