Flutter--Dio封装

614 阅读1分钟

类结构

  • HttpConfig:网络的基本配置
  • HttpApiPARH:请求api地址
  • BaseModel:网络请求model的通用格式
  • ErrorModel:网络请求错误model
  • AppModeVar:请求环境切换(用于dev,test,release切换)
  • DioManager:Dio单例,简要封装get、post、requestHttp请求
  • **Interceptor:拦截器(请求打印,token失效拦截)

Dio单例封装

  • 单例模式
class DioManager {
  static final DioManager _shareInstance = DioManager._instance();

  factory DioManager() => _shareInstance;

  Dio dio = Dio();

  DioManager._instance() {
    BaseOptions options = BaseOptions(
      baseUrl: HttpConfig.baseURL,
      contentType: Headers.jsonContentType,
      responseType: ResponseType.json,
      headers: HttpConfig.commHeaders,
      connectTimeout: HttpConfig.connectTimeout,
      receiveTimeout: HttpConfig.receiveTimeout,
    );
    // 拦截器配置
    dio = Dio(options)
      ..interceptors.add(HttpLogInterceptor())
      ..interceptors.add(InvalidTokenInterceptor());
  }
}
  • requestHttp封装(可自定义baseUrl,添加请求头),通过block获取数据或者直接return数据。
  • get请求参数通过queryParameters传递,post请求参数通过data传递。
Future requestHttp(
  HttpMethod method,
  String path, {
  Map<String, dynamic>? customHeads,
  data,
  Map<String, dynamic>? queryParameters,
  required Function(dynamic) success,
  required Function(ErrorModel) error,
}) async {
  try {
    if (customHeads != null) {
      dio.options.headers.addAll(customHeads);
    }
    Response response = await dio.request(path,
        data: data,
        queryParameters: queryParameters,
        options: Options(method: HttpMethodValues[method]));
    // JSON序列化
    String jsonStr = json.encode(response.data);
    Map<String, dynamic> map = json.decode(jsonStr);

    var baseModel = BaseModel.fromJson(map);
    if (baseModel.code == 0) {
      // baseModel.data返回的可能是List,也可能是dict
      success(baseModel.data);
      return baseModel.data;
    } else {
      error(ErrorModel(code: baseModel.errCode, errorMsg: baseModel.msg));
    }
  } on DioError catch (e) {

  }
}
  • BaseModel,有没有大神分享下,如果能把类名作为参数传递进去,在requestHttp内部动态的做模型转换,最后直接return出模型的方式?
class BaseModel {
  BaseModel({
    this.code = 0,
    this.errCode = 0,
    required this.msg,
    this.data,
  });

  int code;
  int errCode;
  String msg;
  dynamic data;

  factory BaseModel.fromJson(Map<String, dynamic> json) => BaseModel(
    code: json["code"],
    errCode: json['errCode'],
    msg: json["msg"],
    data: json["data"],
  );

  Map<String, dynamic> toJson() => {
    "code": code,
    "errCode": errCode,
    "msg": msg,
    "data": data,
  };
}

AppModeVar设计

  • 将切换环境保存到本地,BaseURL直接从本地去取。
  • 保存环境而不是URL原因是baseURL和H5URL都可能是跟随环境变化而变化。
/// 本地存储环境变量
enum AppModeType { dev, test, release }

const AppModeTypeJSONS = {
  AppModeType.dev: 'dev',
  AppModeType.test: 'test',
  AppModeType.release: 'release',
};

const Map AppModeTypeBaseURLS = {
  'dev': '',
  'test': '',
  'release': ''
};

const Map AppModeTypeH5URLS = {
  'dev': '',
  'test': '',
  'release': ''
};

class AppModeVar {
  final String modeKey = 'modeType';

  saveAppModeVar(AppModeType mode) {
    setJson(modeKey, AppModeTypeJSONS[mode]);
  }

  String getAppModeVar() {
    return getJson(modeKey) ?? 'release';
  }

  removeAppModeVar() {
    remove(modeKey);
  }

  String returnBaseURL(String modeJSON) {
    return AppModeTypeBaseURLS[modeJSON];
  }

  String returnH5URL(String modeJSON) {
    return AppModeTypeH5URLS[modeJSON];
  }
}