当前位置:网站首页>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
- settings.xml
- Two forms of softmax cross entropy + numpy implementation
- Semantic segmentation correlation
- 异常处理:pyemd或PyEMD找不到
- Copy products with one click from Taobao, tmall, 1688, wechat, jd.com, Suning, taote and other platforms to pinduoduo platform (batch upload baby details Interface tutorial)
- Taobao product details interface (product details page data interface)
- 你真的会写Restful API吗?
- 12. Priority queue and inert queue
- Machine vision Series 2: vs DLL debugging
猜你喜欢
No, just stick to it for 64 days. Find the insertion location
从淘宝,天猫,1688,微店,京东,苏宁,淘特等其他平台一键复制商品到拼多多平台(批量上传宝贝详情接口教程)
10.回退消息
15.federation
Back propagation process of manual BP neural network
6. Pytest generates an allure Report
Object detection: object_ Detection API +ssd target detection model
Class starts! See how smardaten decomposes complex business scenarios
Copy products with one click from Taobao, tmall, 1688, wechat, jd.com, Suning, taote and other platforms to pinduoduo platform (batch upload baby details Interface tutorial)
14.haproxy+keepalived负载均衡和高可用
随机推荐
Not for 58 days. Implement prefix tree
Deep learning training strategy -- warming up the learning rate
MySQL gets the maximum value record by field grouping
Sign the college entrance examination
Why is it necessary to scale the attention before softmax (why divide by the square root of d_k)
Class starts! See how smardaten decomposes complex business scenarios
12.优先级队列和惰性队列
数据库SQL语句实现数据分解的函数查询
How to query the submission number of a version
Kotlin's list, map, set and other collection classes do not specify types
kotlin的List,Map,Set等集合类不指定类型
使用容器部署Jenkins
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
Exception handling: pyemd or pyemd not found
Definition and implementation of stack and queue (detailed)
Labelme cannot open the picture
12. Priority queue and inert queue
Back propagation process of manual BP neural network
不会就坚持59天吧 替换单词
Won't you insist on 71 days? List sorting