简介:
需要导入的库
dio: ^3.0.9
json_serializable: ^3.3.0
dio_cookie_manager: ^1.0.0
dio_http_cache: ^0.2.6
介绍:
在自己的这个封装中集成了
- 显示日志
- 缓存cooker
- 缓存结果
##代码
import 'dart:convert';
import 'package:chuanzhi/contract/api.dart';
import 'package:chuanzhi/contract/config.dart';
import 'package:dio/dio.dart';
import 'package:cookie_jar/cookie_jar.dart';
import 'package:dio_cookie_manager/dio_cookie_manager.dart';
import 'package:dio_http_cache/dio_http_cache.dart';
/// 网络请求的工具类,通过这个方法可以获取到请求成功与请求失败的回调(Respose类)。
class HttpUtils {
/// get 请求的方式
static const String _getRequestMethod = 'get';
/// post 请求的方式
static const String _postRequestMethod = 'post';
/// 创建dio这个网络框架
Dio _dio = Dio();
/// 私有化的HttpUtils 的实例
static HttpUtils _instace;
bool _showDebug;
bool _showCache;
/// httpUtils 的的单例方法
/// 参数:
/// Map<String, dynamic> headers : 请求头,此请求头可以不传递。
/// String baseUrl : baseUrl ,这个baseurl 方法可以替换。当然如果是在真实项目中baseUrl 一般都是一致的。所以此参数可以不传递
/// int connectTimeouts :请求的超时时间,此参数默认是5000,大家可以对于访问数据多的设置此参数,参数可以不传递。
/// int receiveTimeouts : 响应的超时时间,此参数默认为3000,参数可以不传递。
static HttpUtils getInstace(
[Map<String, dynamic> headers,
String baseUrl = APIURL.BASE_URL,
int connectTimeouts = 5000,
int receiveTimeouts = 3000,
bool showDebug = Config.isShowDebug,
bool showCooker = Config.showCooker,
bool showCache = Config.showCache]) {
if (_instace == null) {
_instace = HttpUtils._(headers, baseUrl, connectTimeouts, receiveTimeouts,
showDebug, showCooker, showCache);
}
return _instace;
}
/// 私有化构造方法,只可以通过 getInstace 的空参构造获取到HttpUtils 的实例。
HttpUtils._(Map<String, dynamic> headers, String baseUrl, int connectTimeouts,
int receiveTimeouts, bool showDebug, bool showCooker, bool showCache) {
///1. 如果有header 头,那么就设置,如果没有的话,就不设置
if (headers != null && headers.isNotEmpty) {
_dio.options.headers = headers;
}
/// 2. 设置超时时间
_dio.options.baseUrl = baseUrl;
/// 3. 设置请求的超时时间
_dio.options.connectTimeout = connectTimeouts;
///4.设置接受的超时时间
_dio.options.receiveTimeout = receiveTimeouts;
/// 5.设置是否显示Log日志,默认为false
_dio.interceptors.add(LogInterceptor(responseBody: showDebug));
_showDebug = showDebug;
if (showCooker) {
/// 6. 设置缓存
_dio.interceptors.add(CookieManager(CookieJar()));
}
_showCache = showCache;
if (_showCache) {
_dio.interceptors
.add(DioCacheManager(CacheConfig(baseUrl: baseUrl)).interceptor);
}
}
/// get 请求的方法
/// String path : 此参数是baseUrl 之后的内容。必须要传递
/// Function successCallBack: 此参数是成功的回调
/// Function errCallBack: 此参数是失败的回调
/// Map<String,dynamic> params : 请求的参数,此参数不是必须要传的参数,因为某些请求中没有需要传递的参数。
get(String path, Function successCallBack, Function errCallBack,
[Map<String, dynamic> params, int days = 7]) {
_httprequest(
path, _getRequestMethod, successCallBack, errCallBack, params, days);
}
/// post 请求的方法 , 此方法和上面的get 方法类似 。
post(String path, Map<String, dynamic> params, Function successCallBack,
Function errCallBack,
[int days = 7]) {
_httprequest(
path, _postRequestMethod, successCallBack, errCallBack, params, days);
}
/// http 请求的实现方法
///
_httprequest(
String path,
String method,
Function successCallBack,
Function errCallBack,
Map<String, dynamic> params,
int days,
) async {
Response _response;
Map<String, dynamic> headers = _dio.options.headers;
try {
/// get 请求方式
if (_getRequestMethod == method) {
if (_showCache) {
if (params != null && params.isNotEmpty) {
/// get 请求有参数
_response = await _dio.get(path,
queryParameters: params,
options: buildCacheOptions(Duration(days: days)));
} else {
/// get 请求无参数
_response = await _dio.get(path,
options: buildCacheOptions(Duration(days: days)));
}
} else {
if (params != null && params.isNotEmpty) {
/// get 请求有参数
_response = await _dio.get(path, queryParameters: params);
} else {
/// get 请求无参数
_response = await _dio.get(path);
}
}
} else
/// post 请求方式
if (_postRequestMethod == method) {
if (_showCache) {
if (params != null && params.isNotEmpty) {
_response = await _dio.post(path,
queryParameters: params,
options: buildCacheOptions(Duration(days: days)));
} else {
_response = await _dio.post(path,
options: buildCacheOptions(Duration(days: days)));
}
} else {
if (params != null && params.isNotEmpty) {
_response = await _dio.post(path, queryParameters: params);
} else {
_response = await _dio.post(path);
}
}
}
} on DioError catch (error) {
// 请求错误处理
Response errorResponse;
if (error.response != null) {
errorResponse = error.response;
} else {
/// 555 : 代表的是自己的错误
errorResponse = new Response(statusCode: 555);
}
// 请求超时
if (error.type == DioErrorType.CONNECT_TIMEOUT) {
errorResponse.statusCode = ResultCode.CONNECT_TIMEOUT;
}
// 一般服务器错误
else if (error.type == DioErrorType.RECEIVE_TIMEOUT) {
errorResponse.statusCode = ResultCode.RECEIVE_TIMEOUT;
}
// debug模式才打印
if (_showDebug) {
print('请求异常: ' + error.toString());
print('请求异常url: ' + path);
if (headers != null && headers.isNotEmpty) {
print('请求头: ' + headers.toString());
}
print('method: ' + _dio.options.method);
}
_error(errCallBack, error.message);
return '';
}
// debug模式打印相关数据
if (_showDebug) {
print('请求url: ' + path);
if (headers != null && headers.isNotEmpty) {
print('请求头: ' + headers.toString());
}
if (params != null && params.isNotEmpty) {
print('请求参数: ' + params.toString());
}
if (_response != null) {
print('返回参数: ' + _response.toString());
}
}
Map<String, dynamic> dataMap = json.decode(_response.data);
if (dataMap == null || dataMap['state'] == 0) {
_error(
errCallBack,
'错误码:' +
dataMap['errorCode'].toString() +
',' +
_response.data.toString());
} else if (successCallBack != null) {
successCallBack(dataMap);
}
}
/// 异常的类
_error(Function errorCallBack, String error) {
if (errorCallBack != null) {
errorCallBack(error);
}
}
}
class ResultCode {
//正常返回是1
static const SUCCESS = 1;
//异常返回是0
static const ERROR = 1;
/// When opening url timeout, it occurs.
static const CONNECT_TIMEOUT = -1;
///It occurs when receiving timeout.
static const RECEIVE_TIMEOUT = -2;
/// When the server response, but with a incorrect status, such as 404, 503...
static const RESPONSE = -3;
/// When the request is cancelled, dio will throw a error with this type.
static const CANCEL = -4;
/// read the DioError.error if it is not null.
static const DEFAULT = -5;
}
class Config {
Config._();
/// 是否显示Debug 日志
static const bool isShowDebug = false;
/// 是否保存Cooker
static const bool showCooker = false;
/// 是否使用缓存
static const bool showCache = true;
}
使用
Map<String, String> map = Map();
map['device'] = 'android';
HttpUtils.getInstace().get(
APIURL.GET_DECODE,
(data) {
print('获取数据成功');
print(data);
},
(error) {
print('获取数据失败');
print(error);
},
map,
);
想法:
大家会说这里好多都用不上啊,我只想说以后扩展起来方便。最惭愧的是我自己不自量力的想要修改回调的方法。结果发现,果然自己还是没有办法让回调成功和回调失败都必须传递参数。所以,有哪位大神知道,请在下方告诉我。
在这里感谢 浩仔-Boy写的文章。