首页 > 其他分享 >flutter 对dio进行简单的二次封装

flutter 对dio进行简单的二次封装

时间:2022-12-16 17:12:01浏览次数:34  
标签:code 封装 HttpException dart dio msg return flutter

前言:在项目中,我们往往要对第三方框架进行二次封装,目的在于减小项目对第三方框架的依赖

下载所需要的依赖, 文件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(
  path: '11111'
);

 HttpUtils.post(   path: '1111',   method: HttpMethod.post //可以更改其他的 );

 

标签:code,封装,HttpException,dart,dio,msg,return,flutter
From: https://www.cnblogs.com/luoshang/p/16987781.html

相关文章