当前位置:网站首页>Flutter实战-请求封装(二)之dio
Flutter实战-请求封装(二)之dio
2022-07-29 04:23:00 【蓝面书生】
用了两年的flutter,有了一些心得,不虚头巴脑,只求实战有用,以供学习或使用flutter的小伙伴参考,学习尚浅,如有不正确的地方还望各路大神指正,以免误人子弟,在此拜谢~(原创不易,转发请标注来源和作者)
注意:无特殊说明,flutter版本为3.0+
上篇总结了api的组织结构,这一篇我们探讨一下Flutter 常用请求库Dio的使用和封装。
一.dio
一般http请求我们要关注的点有如下几个:
访问路径,请求方式,请求头部,请求参数,超时时间,返回结果,返回类型等。
注:(对http/https协议不太明白的,需要补课的童鞋可以去看下基础教程https://www.runoob.com/http/http-tutorial.html)
首先看下dio可配置的参数:
BaseOptions({
String? method,
int? connectTimeout,
int? receiveTimeout,
int? sendTimeout,
String baseUrl = '',
Map<String, dynamic>? queryParameters,
Map<String, dynamic>? extra,
Map<String, dynamic>? headers,
ResponseType? responseType = ResponseType.json,
String? contentType,
ValidateStatus? validateStatus,
bool? receiveDataWhenStatusError,
bool? followRedirects,
int? maxRedirects,
RequestEncoder? requestEncoder,
ResponseDecoder? responseDecoder,
ListFormat? listFormat,
this.setRequestContentTypeWhenNoPayload = false,
})
除了基础配置dio还提供了拦截器interceptors,适配器httpClientAdapter,请求方法get,post,delete,put,patch,download等基础的封装,方便我们使用。
二.Http 基础类
class Http {
///定义各类超时时间
static const int CONNECT_TIMEOUT = 10000; // 默认设置10s超时
static const int RECEIVE_TIMEOUT = 3000;
static const int SEND_TIMEOUT = 3000;
Dio? dio;
static Http _instance = Http._internal();
1._internal()获取Dio实例的方法,主要是配置适配器
Http._internal() {
dio = Dio();dio.httpClientAdapter = DefaultHttpClientAdapter()
..onHttpClientCreate = (HttpClient c,lient) {
client.idleTimeout = Duration(milliseconds: CONNECT_TIMEOUT);
};// 添加错误统一处理拦截器
dio!.interceptors.add(ErrorInterceptor());//添加日志拦截器
dio!.interceptors.add(DioLogInterceptor());
2.post方法源码示例
Future post(
String path, {
required String baseUrl,
Map<String, dynamic>? params,
Map<String, dynamic>? headers,
data,
Options? options,
CancelToken? cancelToken,
}) async {
Options requestOptions = options ?? Options();
//requestOptions.baseUrl = baseUrl;
Map<String, dynamic>? _authorization = headers ?? getAuthorizationHeader();
if (_authorization != null) {
requestOptions = requestOptions.copyWith(headers: _authorization);
}
dio!.options.baseUrl = baseUrl;
dio!.options.connectTimeout = CONNECT_TIMEOUT;
dio!.options.receiveTimeout = RECEIVE_TIMEOUT;
dio!.options.sendTimeout = SEND_TIMEOUT;
var response;
var timeout = Duration(milliseconds: dio!.options.connectTimeout);
cancelToken = CancelToken();
var t = Timer(timeout, () {
if (response == null) {
cancelToken!.cancel();
}
});
response =
await dio!.post(path, data: data, queryParameters: params, options: requestOptions, cancelToken: cancelToken);
t.cancel();
return response.data;
}
cancelToken 是dio提供的一个非常有用的东西,可以主动在返回超时时候,主动结束请求,并触发DioErrorType.cancel的错误事件。
三.httpUtils 加强封装
1.添加是否等待处理
还以post为例,我们定义一个方法调用http的基础类
static Future post(String path,{data,required String baseUrl,
Map<String, dynamic>? params,
Options? options,
CancelToken? cancelToken,
bool showLoading = false}
这里加了一个参数showLoading,在我们实际开发过程中,有一些操作要阻断用户操作,等待接口请求,一些是不需要用户感知的请求,我们可以在所有api中,默认添加该参数为false,有必要阻断用户的时候调用的时候将该参数设置成为true,举个例子如下:
/// 忘记密码
static Future<String> forgetPassword(dynamic param, { bool showLoading= false}) async {
var res = await HttpUtils.post(_forgetPassword, data: param, baseUrl: "xxx" showLoading: showLoading);
return res;
}
当判断需要loading 的时候
if (showLoading) {
showLoadingDialog();
}
作者使用的是flutter_smart_dialog: ^4.5.3+7,使用比较简单,你可以自己去封装所需要的loading样式。
2.定义统一返回类型
class ApiResponse<T> implements Exception {
String? errorMsg;
String? msg;
int? code;
T? data;
ApiResponse(this.msg);
ApiResponse.error(String msg) {
toastMsg(msg);
}
@override
String toString() {
return "Msg : $msg \n errorMsg : $errorMsg \n Data : $data";
}
ApiResponse.fromJson(Map<String, dynamic> json) {
msg = json['msg'];
errorMsg = json['errorMsg'];
code = json['code'];
data = json['data'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['msg'] = this.msg;
data['errorMsg'] = this.errorMsg;
data['code'] = this.code;
data['data'] = this.data;
return data;
}
}
3.返回处理
判断后台返回的正确code,则返回结果,完结后清除loading状态。
源码如下
class HttpUtils {
static Future post(String path,
{data,
required String baseUrl,
Map<String, dynamic>? params,
Options? options,
CancelToken? cancelToken,
bool showLoading = false,
bool canNull = false,
Function(Object?)? onError,
bool errorToast = true,
bool isolate = true}) async {
if (showLoading) {
showLoadingDialog(path: path);
}
return Http()
.post(
path,
baseUrl: baseUrl,
data: data,
params: params,
options: options,
cancelToken: cancelToken,
)
.then((value) {
var result = ApiResponse.fromJson(value is Map ? value : jsonDecode(value));
if (result.code == 2000) {
return result.data;
} else {
throw ApiResponse(result.msg!);
}
}).onError((error, stackTrace) {
if (onError != null) {
onError(error);
}
if (error is RemoteError) {
toastMsg("网络连接失败", displayType: SmartToastType.last);
} else if (error is ApiResponse) {
toastMsg(error.msg!);
} else {
toastMsg("未知错误");
}
throw Exception(error.toString());
}). whenComplete(() {
if (showLoading) {
SmartDialog.dismiss();
}
});}
边栏推荐
- Realize the effect of univariate quadratic equation through JS. Enter the coefficients of a, B and C to calculate the values of X1 and x2
- Beginner: array & String
- Two forms of softmax cross entropy + numpy implementation
- 11.备份交换机
- Kotlin's list, map, set and other collection classes do not specify types
- 异常解决:cococaption包出现找不到edu.stanford.nlp.semgraph.semgrex.SemgrexPattern错误
- 一个公司的面试笔记
- SQL time fuzzy query datediff() function
- 全屋WiFi方案:Mesh路由器组网和AC+AP
- [k210 stepping pit] pytorch model is converted to kmodel and used on dock. (ultimately not achieved)
猜你喜欢
随机推荐
(.*?) regular expression
Coding questions encountered in the interview
不会就坚持68天吧 狒狒吃香蕉
C language force buckle question 61 of the rotating list. Double ended queue and construction of circular linked list
On quotation
WebRTC实现简单音视频通话功能
Not 67 days, square root
Shielding ODBC load balancing mode in gbase 8A special scenarios?
Semantic segmentation correlation
数据库SQL语句实现数据分解的函数查询
全屋WiFi方案:Mesh路由器组网和AC+AP
Locally call tensorboard and Jupiter notebook on the server (using mobaxterm)
Shell string segmentation
It won't last for 65 days. It only appears once
Jenkins 参数化构建中 各参数介绍与示例
通过js来实现一元二次方程的效果,输入a,b,c系数后可计算出x1和x2的值
不会就坚持70天吧 数组中第k大的数
Deep learning training strategy -- warming up the learning rate
一个公司的面试笔记
The data source is SQL server. I want to configure the incremental data of the last two days of the date field updatedate to add