Flutter网络封装(一)

引言

flutter网络请求我们使用dio库来实现:

dependencies:
  flutter:
    sdk: flutter
  dio: ^3.0.10

一个基础网络库,通常我们将其分成两个部分:

  1. 基础网络层
  2. 数据模型转换层

那今天,我们先来实现基础网络层的功能封装

新建 base_request.dart 文件,封装requestOptions,并对外提供内容注入能力(子类重写):
typedef ProgressCallback = void Function(int count, int total);

abstract class BaseRequest {
  String get path;
  String get method => 'POST';
  int get connectTimeout => 5000;
  int get receiveTimeout => 5000;
  int get sendTimeout => 5000;
  Map get headers => null;
  ProgressCallback get onReceiveProgress => null;
  bool get showErrorToast => true;

  RequestOptions requestOptions() {
    return RequestOptions(
      path: path,
      method: method,
      connectTimeout: connectTimeout,
      receiveTimeout: receiveTimeout,
      sendTimeout: sendTimeout,
      cancelToken: cancelToken,
      headers: headers,
      onReceiveProgress: onReceiveProgress,
      responseType: ResponseType.json,
      extra: {
        'showErrorToast': showErrorToast,
      },
    );
  }
}

在基类上面再封装一层,用于抽象具体的请求方法:

abstract class BaseJsonRequest with BaseRequest {
  //dio 需要调用者注入进来
  Dio get dio;
  Set get successCodes => {0};

  Future request() async {
    try {
      final response = await dio.request>(
        path,
        data: data,
        options: requestOptions(),
      );
      _ResponsBaseModel baseModel = _ResponsBaseModel.fromMap(
        response.data,
        successCodes,
      );
      //添加业务数据结构判断
      if (baseModel.success) {
        return baseModel;
      } else {
        if (showErrorToast) {
          Toast.show(baseModel.message)
        }
        throw error;
      }
    } catch (e) {
      if (showErrorToast) {
        //添加处理暴露异常
      }
      rethrow;
    }
  }

  Future execute() async {
    return null;
  }
}
该工具类不能直接使用,需要被具体业务方继承使用,path不能为空

业务数据结构模型,统一接口返回的数据结构

 class _ResponsBaseModel {
  int code;
  String message;
  dynamic data;
  Set successCodes;
  PDResponsBaseModel({
    this.code,
    this.data,
    this.message,
    this.successCodes,
  });
  bool get success => successCodes != null && successCodes.contains(code);
  factory _PDResponsBaseModel.fromMap(
    Map map,
    Set successCodes,
  ) {
    return _PDResponsBaseModel(
      code: (map['code'] as int) ?? -1,
      message: (map['message'] as String) ?? '',
      data: map['data'],
      successCodes: successCodes,
    );
  }
}

具体使用时这么用:
新建一个类用于继承BaseJsonRequest,业务方直接调用execute方法进行网络请求,返回结构为数据模型实例

class MemberInfoRequest extends BaseJsonRequest {
  final String identity;
  MemberInfoRequest(this.identity);
  @override
  String get path => '/getMemberInfo';
  @override
  Dio get dio => Dio(); //dio可自行封装成全局单例工具类,并在初始化时添加拦截器等
  @override
  get data => {'identity': identity, 'identityType': 3};

  @override
  Future execute() {
    return request().then((value) {
      return MemberInfo.fromJson(value.mapData);
    });
  }
}

拦截器怎么写?

class LoggingInterceptor extends Interceptor {
  LoggingInterceptor();
  @override
  Future onRequest(RequestOptions options) {
    //options.data 进行入参插入操作
    return Future.value(options);
  }
  @override
  Future onResponse(Response response) {
    return Future.value(response);
  }
  @override
  Future onError(DioError err) async {
    return err;
  }
}
//将拦截器设置给dio实例
dio.interceptors.addAll([LoggingInterceptor()]);
以上便是网络请求层的一个简单的封装。

你可能感兴趣的:(Flutter网络封装(一))