Flutter--网络请求(三)dio封装网络请求框架

dio简介

  • dio库支持文件的上传和下载,Cookie管理、FormData、请求/取消、拦截器等,和Android中的OkHttp库相似

基本用法

import 'package:dio/dio.dart';

_loadDataGet() async {
  try {
    Response response = await Dio().get("https://www.baidu.com");
    print(response);
  } catch (e) {
    print(e);
  }
}

_loadDataPost() async {
  try {
    Response response = await Dio().post("path", data: {});
    print(response);
  } catch (e) {
    print(e);
  }
}

Dio单例

var dio = new Dio(BaseOptions(
  baseUrl: "url",
  connectTimeout: 5000,
  receiveTimeout: 10000,
  
  headers:{
    HttpHeaders.userAgentHeader: "dio",
    "api": "1.0.0",
  },
  contentType: ContentType.json,
  responseType: ResponseType.plain
));

Dio拦截器

  • 官方示例
dio.interceptors.add(InterceptorsWrapper(
onRequest:(RequestOptions options) async {
    // 请求发送前处理
return options; //continue
},
onResponse:(Response response) async {
// 在返回响应数据之前做一些预处理
return response; // continue
},
onError: (DioError e) async {
// 当请求失败时做一些预处理
return e;//continue
}
));
  • 注意:
    • 在拦截器做request处理时,可以直接返回options,这个时候会继续处理then方法里的逻辑,如果想要完成请求并返回一些自定义的数据,可以返回一个Response对象或返回dio.resolve(data),可以使得请求终止,上层的then会被调用,then中返回的数据是自定义的数据

封装dio网络请求

  • 首先创建一个单例
class HttpRequest {
  static String _baseUrl = Api.BASE_URL;
  static HttpRequest instance;

  Dio dio;
  BaseOptions options; // 基类请求配置,还可以使用Options单次请求配置,RequestOptions实际请求配置对多个域名发起请求

  CancelToken cancelToken = CancelToken();

  static HttpRequest getInstance() {
    if (instance == null) {
      instance = HttpRequest();
    }
    return instance;
  }
}
  • 配置并初始化dio参数

HttpRequest() {
  options = BaseOptions(
    // 访问url
    baseUrl: _baseUrl,
    // 连接超时时间
    connectTimeout: 5000,
    // 响应流收到数据的间隔
    receiveTimeout: 15000,
    // http请求头
    headers: {"version": "1.0.0"},
    // 接收响应数据的格式
    responseType: ResponseType.plain,
  );
  dio = Dio(options);
  
  // 在拦截其中加入Cookie管理器
  dio.interceptors.add(CookieManager(CookieJar()));
  
  //添加拦截器
  dio.interceptors.add(InterceptorsWrapper(onRequest: (RequestOptions options) {
    // Do something before request is sent
    return options; //continue
  }, onResponse: (Response response) {
    // Do something with response data
    return response; // continue
  }, onError: (DioError e) {
    // Do something with response error
    return e; //continue
  }));
}

  • 取消请求
// cancelToken可用于多个请求,也可同时取消多个请求
void cancelRequests(CancelToken token) {  
    token.cancel("cancelled");
}
  • get请求
get(url,
    {data,
      options,
      cancelToken,
      BuildContext context,
      Function successCallBack,
      Function errorCallBack}) async {
  Response response;
  try {
    response = await dio.get(url,
        queryParameters: data, options: options, cancelToken: cancelToken);
  } on DioError catch (e) {
    handlerError(e);
  }
  if (response.data != null) {
    BaseResponse baseResponse =
    BaseResponse.fromJson(json.decode(response.data));
    if (baseResponse != null) {
      switch (baseResponse.errorCode) {
        case 成功状态码:
          successCallBack(jsonEncode(baseResponse.data));
          break;
        case 其他状态码:
          errorCallBack(baseResponse.errorCode, baseResponse.errorMessage);

          break;
        default:
          errorCallBack(baseResponse.errorCode, baseResponse.errorMessage);
          break;
      }
    } else {
      errorCallBack(Constants.NETWORK_JSON_EXCEPTION, "网络数据问题");
    }
  } else {
    errorCallBack(Constants.NETWORK_ERROR, "网络出错啦,请稍后重试");
  }
}
  • 注意:

    • url:请求地址
    • data:请求参数
    • options:请求配置
    • cancelToken:取消标识
  • post请求

post(url,
    {data,
      options,
      cancelToken,
      BuildContext context,
      Function successCallBack,
      Function errorCallBack}) async {
  Response response;
  try {
    response = await dio.post(url,
        queryParameters: data, options: options, cancelToken: cancelToken);
  } on DioError catch (e) {
    handlerError(e);
  }
  if (response.data != null) {
    BaseResponse baseResponse =
    BaseResponse.fromJson(json.decode(response.data));
    if (baseResponse != null) {
      switch (baseResponse.errorCode) {
        case 成功状态码:
          successCallBack(jsonEncode(baseResponse.data));
          break;
        case 其他状态码:
          errorCallBack(baseResponse.errorCode, baseResponse.errorMessage);
          break;
        default:
          errorCallBack(baseResponse.errorCode, baseResponse.errorMessage);
          break;
      }
    } else {
      errorCallBack(Constants.NETWORK_JSON_EXCEPTION, "网络数据问题");
    }
  } else {
    errorCallBack(Constants.NETWORK_ERROR, "网络出错啦,请稍后重试");
  }
}
  • 下载文件

downloadFile(urlPath, savePath) async {
  Response response;
  try {
    response = await dio.download(urlPath, savePath,onReceiveProgress: (int count, int total){
      //进度
      print("$count $total");
    });
    print('downloadFile success---------${response.data}');
  } on DioError catch (e) {
    print('downloadFile error---------$e');
    handlerError(e);
  }
  return response.data;
}
  • 错误处理
handlerError(DioError e) {
  if (e.type == DioErrorType.CONNECT_TIMEOUT) {
    print("连接超时");
  } else if (e.type == DioErrorType.SEND_TIMEOUT) {
    print("请求超时");
  } else if (e.type == DioErrorType.RECEIVE_TIMEOUT) {
    print("响应超时");
  } else if (e.type == DioErrorType.RESPONSE) {
    print("响应异常");
  } else if (e.type == DioErrorType.CANCEL) {
    print("请求取消");
  } else {
    print("未知错误");
  }
}

你可能感兴趣的:(Flutter)