Flutter完整的Dio网络框架null空安全二次封装。
admin
2024-01-25 10:47:28
所需依赖添加在项目中的pubspec.yaml中:
dio: ^4.0.6                                       #网络请求
connectivity_plus: ^2.3.6                         #网络监测
pretty_dio_logger: ^1.1.1                         #日志打印
class HttpRequest {// 单例模式使用Http类,static final HttpRequest _instance = HttpRequest._internal();factory HttpRequest() => _instance;static late final Dio dio;/// 内部构造方法HttpRequest._internal() {/// 初始化dioBaseOptions options = BaseOptions(connectTimeout: HttpOptions.connectTimeout,receiveTimeout: HttpOptions.receiveTimeout,sendTimeout: HttpOptions.sendTimeout,baseUrl: HttpOptions.baseUrl);dio = Dio(options);/// 添加各种拦截器dio.interceptors.add(ErrorInterceptor());dio.interceptors.add(PrettyDioLogger(requestHeader: true,requestBody: true,responseHeader: true,responseBody: true));}/// 封装request方法Future request({required String path,required HttpMethod method,dynamic data,Map? queryParameters,bool showLoading = true,bool showErrorMessage = true,}) async {const Map methodValues = {HttpMethod.get: 'get',HttpMethod.post: 'post',HttpMethod.put: 'put',HttpMethod.delete: 'delete',HttpMethod.patch: 'patch',HttpMethod.head: 'head'};//动态添加header头Map headers = Map();headers["version"] = "1.0.0";Options options = Options(method: methodValues[method],headers: headers,);try {if (showLoading) {EasyLoading.show(status: 'loading...');}Response response = await HttpRequest.dio.request(path,data: data,queryParameters: queryParameters,options: options,);return response.data;} on DioError catch (error) {HttpException httpException = error.error;if (showErrorMessage) {EasyLoading.showToast(httpException.msg);}} finally {if (showLoading) {EasyLoading.dismiss();}}}
}enum HttpMethod {get,post,delete,put,patch,head,
}

class ErrorInterceptor extends Interceptor {@overridevoid onError(DioError err, ErrorInterceptorHandler handler) async {/// 根据DioError创建HttpExceptionHttpException httpException = HttpException.create(err);/// dio默认的错误实例,如果是没有网络,只能得到一个未知错误,无法精准的得知是否是无网络的情况/// 这里对于断网的情况,给一个特殊的code和msgif (err.type == DioErrorType.other) {var connectivityResult = await (Connectivity().checkConnectivity());if (connectivityResult == ConnectivityResult.none) {httpException = HttpException(code: -100, msg: 'None Network.');}}/// 将自定义的HttpExceptionerr.error = httpException;/// 调用父类,回到dio框架super.onError(err, handler);}
}

class HttpException implements Exception {final int code;final String msg;HttpException({this.code = -1,this.msg = 'unknow error',});@overrideString toString() {return 'Http Error [$code]: $msg';}factory HttpException.create(DioError error) {/// dio异常switch (error.type) {case DioErrorType.cancel:{return HttpException(code: -1, msg: 'request cancel');}case DioErrorType.connectTimeout:{return HttpException(code: -1, msg: 'connect timeout');}case DioErrorType.sendTimeout:{return HttpException(code: -1, msg: 'send timeout');}case DioErrorType.receiveTimeout:{return HttpException(code: -1, msg: 'receive timeout');}case DioErrorType.response:{try {int statusCode = error.response?.statusCode ?? 0;// String errMsg = error.response.statusMessage;// return ErrorEntity(code: errCode, message: errMsg);switch (statusCode) {case 400:{return HttpException(code: statusCode, msg: 'Request syntax error');}case 401:{return HttpException(code: statusCode, msg: 'Without permission');}case 403:{return HttpException(code: statusCode, msg: 'Server rejects execution');}case 404:{return HttpException(code: statusCode, msg: 'Unable to connect to server');}case 405:{return HttpException(code: statusCode, msg: 'The request method is disabled');}case 500:{return HttpException(code: statusCode, msg: 'Server internal error');}case 502:{return HttpException(code: statusCode, msg: 'Invalid request');}case 503:{return HttpException(code: statusCode, msg: 'The server is down.');}case 505:{return HttpException(code: statusCode, msg: 'HTTP requests are not supported');}default:{return HttpException(code: statusCode, msg: error.response?.statusMessage ?? 'unknow error');}}} on Exception catch (_) {return HttpException(code: -1, msg: 'unknow error');}}default:{return HttpException(code: -1, msg: error.message);}}}
}

class HttpOptions {/// 超时时间;单位是msstatic const int connectTimeout = 15000;static const int receiveTimeout = 15000;static const int sendTimeout = 15000;/// 地址域名前缀static const String baseUrl = '************';}

/// 调用底层的request,重新提供get,post等方便方法
class HttpUtils {static HttpRequest httpRequest = HttpRequest();/// getstatic Future get({required String path,Map? queryParameters,bool showLoading = true,bool showErrorMessage = true,}) {return httpRequest.request(path: path,method: HttpMethod.get,queryParameters: queryParameters,showLoading: showLoading,showErrorMessage: showErrorMessage,);}/// poststatic Future post({required String path,required HttpMethod method,dynamic data,bool showLoading = true,bool showErrorMessage = true,}) {return httpRequest.request(path: path,method: HttpMethod.post,data: data,showLoading: showLoading,showErrorMessage: showErrorMessage,);}}

相关内容

热门资讯

山水皆有情!丽江两山一江的千年... 去过丽江、走过虎跳峡的人,大概率都听过哈巴雪山和金沙江的传说。很多人站在峡谷之下,望着奔腾不息的金沙...
活力中国调研行丨“殷”你而来 ... 9月12日,游客在殷墟博物馆“甲骨文展厅”内参观。位于河南省安阳市的殷墟博物馆新馆是首个全景式展现商...
浦江之夜赴美好相逢,第37届上... 9月12日晚,黄浦江畔灯火璀璨,第37届上海旅游节大巡游在外滩中山东一路上演。不少观众早早便来到外滩...
美丽中国丨秋韵紫鹊界 梯田入画... 这是9月11日拍摄的紫鹊界梯田(无人机照片)。 金秋九月,湖南省娄底市新化县紫鹊界梯田稻谷渐次成熟。...
中国之巅奏响《共同的节日》,千... 千吨阻尼器,“迎世赛、游上海旅游节”。9月13日,由上海市文化和旅游局指导推出上海旅游·会客│巅峰之...