前言:在项目中,我们往往要对第三方框架进行二次封装,目的在于减小项目对第三方框架的依赖
下载所需要的依赖, 文件pubspec.yaml
dependencies:dio: ^4.0.6 //http请求依赖 connectivity_plus: ^2.3.6 // 网络状态依赖 pretty_dio_logger: ^1.1.1 //日志依赖 flutter_easyloading: ^3.0.3 //弹框提示依赖
下面为我的文件结构(具体的可以自己定义)
entity http.dart interceptor.dart options.dart request.dart
http.dart文件内容
import 'package:dio/dio.dart'; import 'package:pretty_dio_logger/pretty_dio_logger.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; //辅助配置 import 'options.dart'; import 'interceptor.dart'; class HttpRequest { // 单例模式使用Http类, static final HttpRequest _instance = HttpRequest._internal(); factory HttpRequest() => _instance; static late final Dio dio; /// 内部构造方法 HttpRequest._internal() { /// 初始化dio BaseOptions 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<String, dynamic>? 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<String, dynamic> headers = <String, dynamic>{}; 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, }
interceptor.dart文件内容
import 'package:dio/dio.dart'; import 'package:connectivity_plus/connectivity_plus.dart'; class ErrorInterceptor extends Interceptor { @override void one rror(DioError err, ErrorInterceptorHandler handler) async { /// 根据DioError创建HttpException HttpException httpException = HttpException.create(err); /// dio默认的错误实例,如果是没有网络,只能得到一个未知错误,无法精准的得知是否是无网络的情况 /// 这里对于断网的情况,给一个特殊的code和msg if (err.type == DioErrorType.other) { var connectivityResult = await (Connectivity().checkConnectivity()); if (connectivityResult == ConnectivityResult.none) { httpException = HttpException(code: -100, msg: 'None Network.'); } } /// 将自定义的HttpException err.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', }); @override String 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); } } } }
options.dart
// 超时时间 class HttpOptions { //地址域名前缀 static const String baseUrl = ''; //单位时间是ms static const int connectTimeout = 1500; static const int receiveTimeout = 1500; static const int sendTimeout = 1500; }
request.dart文件内容
import 'http.dart'; /// 调用底层的request,重新提供get,post等方便方法 class HttpUtils { static HttpRequest httpRequest = HttpRequest(); /// get static Future get({ required String path, Map<String, dynamic>? queryParameters, bool showLoading = true, bool showErrorMessage = true, }) { return httpRequest.request( path: path, method: HttpMethod.get, queryParameters: queryParameters, showLoading: showLoading, showErrorMessage: showErrorMessage, ); } /// post static 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, ); } }
使用方法
import '../entity/request.dart'; HttpUtils.get(HttpUtils.post( path: '1111', method: HttpMethod.post //可以更改其他的 );
path: '11111'
);
标签:code,封装,HttpException,dart,dio,msg,return,flutter From: https://www.cnblogs.com/luoshang/p/16987781.html