Flutter网络库封装

  • Post author:
  • Post category:其他




添加依赖

pubspec.yaml

dependencies:
  flutter:
    sdk: flutter
  dio: ^3.0.9 // dio 网络库



封装基础请求

base_request.dart

abstract class BaseRequest {
  var pathParams; // 请求参数
  var useHttps = true; // 是否使用 https
  Map<String, String> params = Map(); // 请求参数
  Map<String, String> header = Map(); // header 参数

  // 请求host
  String authority() {
    return "api.devio.org";
  }

  // 构建 url
  String url() {
    Uri uri;
    var pathStr = path();

    // 拼接path参数
    if (pathParams != null) {
      if (path().endsWith("/")) {
        pathStr = "${path()}$pathParams";
      } else {
        pathStr = "${path()}/$pathParams";
      }
    }

    // http 和 https 切换
    if (useHttps) {
      uri = Uri.https(authority(), pathStr);
    } else {
      uri = Uri.http(authority(), pathStr);
    }

    return uri.toString();
  }

  // 添加请求参数
  BaseRequest add(String k, String v) {
    params[k] = v;
    return this;
  }

  // 添加 header
  BaseRequest addHeader(String k, String v) {
    header[k] = v;
    return this;
  }

  //--------------------------------------- 需要子类实现的方法
  // 是否需要登录
  bool needLogin();
  // 请求方式
  HttpMethod httpMethod();
  // 请求路径
  String path();
}


使用基础请求

class TestRequest extends BaseRequest {
  @override
  bool needLogin() {
    return false;
  }

  @override
  String path() {
    return "/uapi/test/test";
  }

  @override
  HttpMethod httpMethod() {
    return HttpMethod.GET;
  }
}



封装网络请求

作为网络请求入口,提供基于 http 和 dio 网络框架的封装

hi_net.dart

class HiNet {
  // 静态私有成员,没有初始化
  static HiNet _instance;

  // 私有构造函数
  HiNet._();

  static HiNet getInstance() {
    if (_instance == null) {
      _instance = HiNet._();
    }
    return _instance;
  }

  /**
   * 发送网络请求的类
   */
  Future fire(BaseRequest request) async {
    HiNetResponse response;
    var error;
    try {
      response = await send(request);
    } on HiNetError catch (e) {
      error = e;
      response = e.data;
      printLog(e.message);
    } catch (e) {
      error = e;
      printLog(e);
    }

    if (response == null) {
      printLog(error);
    }

    var result = response.data;
    print(result);

    var status = response.statusCode;
    switch (status) {
      case 200:
        return result;
      case 401:
        throw NeedLogin();
      case 403:
        throw NeedAuth(result.toString(), data: result);
      default:
        throw HiNetError(status, result.toString(), data: result);
    }
  }

  Future<dynamic> send(BaseRequest request) async {
    printLog('url:${request.url()}');

    // 使用 Mock 发送请求
    HiNetAdapter adapter = DioAdapter();
    return adapter.send(request);
  }

  void printLog(log) {
    print('hi_net:${log.toString()}');
  }
}



封装统一网络返回数据

hi_net_adapter.dart


// 网络请求抽象类
abstract class HiNetAdapter {
  Future<HiNetResponse<T>> send<T>(BaseRequest request);
}

/// 统一网络层返回格式
class HiNetResponse<T> {
  T data;
  BaseRequest request;
  int statusCode;
  String statusMessage;
  dynamic extra;

  @override
  String toString() {
    if (data is Map) {
      return json.encode(data);
    }
    return data.toString();
  }

  HiNetResponse(
      {this.data,
      this.request,
      this.statusCode,
      this.statusMessage,
      this.extra});
}



封装网络异常数据

hi_error.dart

// 需要登录的异常
class NeedLogin extends HiNetError {
  NeedLogin({int code: 401, String message: '请先登录'}) : super(code, message);
}

// 需要授权的异常
class NeedAuth extends HiNetError {
  NeedAuth(String message, {int code: 403, dynamic data})
      : super(code, message, data: data);
}

// 网络异常统一格式类
class HiNetError implements Exception {
  final int code;
  final String message;
  final dynamic data;

  HiNetError(this.code, this.message, {this.data});
}



实现基于 HiNetAdapter 的 http 和 dio 请求适配器

dio_adapter.dart

class DioAdapter extends HiNetAdapter {
  @override
  Future<HiNetResponse<T>> send<T>(BaseRequest request) async {
    var response, options = Options(headers: request.header);
    var error;
    try {
      // 发送请求
      if (request.httpMethod() == HttpMethod.GET) {
        response = await Dio().get(request.url(),
            queryParameters: request.params, options: options);
      } else if (request.httpMethod() == HttpMethod.POST) {
        response = await Dio()
            .post(request.url(), data: request.params, options: options);
      } else if (request.httpMethod() == HttpMethod.DELETE) {
        response = await Dio()
            .delete(request.url(), data: request.params, options: options);
      }
    } on DioError catch (e) {
      error = e;
      response = e.response;
    }
    if (error != null) {
      /// 抛出HiNetError
      throw HiNetError(response?.statusCode ?? -1, error.toString(),
          data: buildRes(response, request));
    }
    return buildRes(response, request);
  }

  /// 构建 HiNetResponse
  HiNetResponse buildRes(response, BaseRequest request) {
    return HiNetResponse(
        data: response.data,
        request: request,
        statusCode: response.statusCode,
        statusMessage: response.statusMessage,
        extra: response);
  }
}



网络封装库使用

 // 发送网络请求
    BaseRequest request = new TestRequest();
    request
        .add('aa', 'ddd') // 添加请求参数
        .addHeader('token','124'); // 添加header
    try {
      var result = await HiNet.getInstance().fire(request);
      print(result);
    } on NeedAuth catch (e) {
      print(e);
    } on NeedLogin catch (e) {
      print(e);
    } on HiNetError catch (e) {
      print(e);
    }



源码下载


点击下载



版权声明:本文为weixin_43800535原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。