Flutter - dio 簡單封裝

demo 地址: https://github.com/iotjin/jh_flutter_demo

Flutter Dio簡單二次封裝和自定義Header
Flutter Dio二次封裝
Flutter Dio封裝與使用
Flutter 封裝 dio,支持 Restful Api
Flutter 網(wǎng)絡(luò)請求框架封裝

結(jié)構(gòu)

apis 文件配置API 地址
dio_utils 文件是對dio的封裝
error_handle 文件是異常處理
http_utils 項目接口請求 管理類 ,(最終是通過調(diào)用這個文件進行網(wǎng)絡(luò)請求)
log_utils 日志打印的一個第三方, 可加可不加

ps: 暫時沒有加攔截器

結(jié)構(gòu)

調(diào)用

import 'package:jh_flutter_demo/http/http_utils.dart';

HttpUtils.PostRequest(APIType.Login,{"userName": _name, "pwd": _pwd}, success: (data) {

}, fail: (code) {

});

apis

class APIs {
  //url 前綴
  static const String apiPrefix =
"https://www.fastmock.site/mock/1010b262a743f0b06c565c7a31ee9739/root";
  //登錄接口
  static String login = "/login";
}

//接口類型,依次往下加
enum APIType {
  Login,
  GetPage,
}
//使用:APITypeValues[APIType.Login]
const APITypeValues = {
  APIType.Login: "/login",
  APIType.GetPage: "/getPageArrDic"
};

dio_utils

import 'dart:convert';

import 'package:dio/dio.dart';
import 'package:connectivity/connectivity.dart';

import 'apis.dart';
import 'log_utils.dart';
import 'error_handle.dart';

const int _connectTimeout = 15000; //15s
const int _receiveTimeout = 15000;
const int _sendTimeout = 10000;

typedef Success<T> = Function(T data);
typedef Fail = Function(int code, String msg);
class DioUtils {
  // default options
  static const String TOKEN = '';

  static Dio _dio;

  // 創(chuàng)建 dio 實例對象
  static Dio createInstance() {
    if (_dio == null) {
      /// 全局屬性:請求前綴歹叮、連接超時時間诗舰、響應(yīng)超時時間
      var options = BaseOptions(
        /// 請求的Content-Type秽浇,默認值是"application/json; charset=utf-8".
        /// 如果您想以"application/x-www-form-urlencoded"格式編碼請求數(shù)據(jù),
        /// 可以設(shè)置此選項為 `Headers.formUrlEncodedContentType`,  這樣[Dio]就會自動編碼請求體.
//        contentType: Headers.formUrlEncodedContentType, // 適用于post form表單提交
        responseType: ResponseType.json,
        validateStatus: (status) {
          // 不使用http狀態(tài)碼判斷狀態(tài)返吻,使用AdapterInterceptor來處理(適用于標(biāo)準REST風(fēng)格)
          return true;
        },
        baseUrl: APIs.apiPrefix,
//        headers: httpHeaders,
        connectTimeout: _connectTimeout,
        receiveTimeout: _receiveTimeout,
        sendTimeout: _sendTimeout,
      );
      _dio = new Dio(options);
    }
    return _dio;
  }

  // 清空 dio 對象
  static clear() {
    _dio = null;
  }

  // 請求授翻,返回參數(shù)為 T
  // method:請求方法去扣,Method.POST等
  // path:請求地址
  // params:請求參數(shù)
  // success:請求成功回調(diào)
  // error:請求失敗回調(diào)
  static Future request<T>(Method method, String path, dynamic params,
      {Success success, Fail fail}) async {
    try {
      //沒有網(wǎng)絡(luò)
      var connectivityResult = await (new Connectivity().checkConnectivity());
      if (connectivityResult == ConnectivityResult.none) {
        _onError(ExceptionHandle.net_error, '網(wǎng)絡(luò)異常,請檢查你的網(wǎng)絡(luò)宁改!', fail);
        return;
      }
      Dio _dio = createInstance();
      Response response = await _dio.request(path,
          data: params, options: Options(method: MethodValues[method]));
      if (response != null) {
        if (success != null) {
          success(response.data);
        }
      } else {
        _onError(ExceptionHandle.unknown_error, '未知錯誤', fail);
      }
    } on DioError catch (e) {
//      LogUtils.print_('請求出錯:' + e.toString());
      final NetError netError = ExceptionHandle.handleException(e);
      _onError(netError.code, netError.msg, fail);
    }
  }
}

/// 自定義Header
Map<String, dynamic> httpHeaders = {
  'Accept': 'application/json,*/*',
  'Content-Type': 'application/json',
  'token': DioUtils.TOKEN
};

void _onError(int code, String msg, Fail fail) {
  if (code == null) {
    code = ExceptionHandle.unknown_error;
    msg = '未知異常';
  }
  LogUtils.print_('接口請求異常: code: $code, msg: $msg');
  if (fail != null) {
    fail(code, msg);
  }
}

Map<String, dynamic> parseData(String data) {
  return json.decode(data) as Map<String, dynamic>;
}

enum Method { GET, POST, DELETE, PUT, PATCH, HEAD }
//使用:MethodValues[Method.POST]
const MethodValues = {
  Method.GET: "get",
  Method.POST: "post",
  Method.DELETE: "delete",
  Method.PUT: "put",
  Method.PATCH: "patch",
  Method.HEAD: "head",
};

error_handle

import 'dart:io';

import 'package:dio/dio.dart';


class ExceptionHandle {
  static const int success = 200;
  static const int success_not_content = 204;
  static const int unauthorized = 401;
  static const int forbidden = 403;
  static const int not_found = 404;

  static const int net_error = 1000;
  static const int parse_error = 1001;
  static const int socket_error = 1002;
  static const int http_error = 1003;
  static const int timeout_error = 1004;
  static const int cancel_error = 1005;
  static const int unknown_error = 9999;

  static NetError handleException(DioError error) {
    if (error is DioError) {
      if (error.type == DioErrorType.DEFAULT ||
          error.type == DioErrorType.RESPONSE) {
        dynamic e = error.error;
        if (e is SocketException) {
          return NetError(socket_error, '網(wǎng)絡(luò)異常缕探,請檢查你的網(wǎng)絡(luò)!');
        }
        if (e is HttpException) {
          return NetError(http_error, '服務(wù)器異常还蹲!');
        }
        if (e is FormatException) {
          return NetError(parse_error, '數(shù)據(jù)解析錯誤爹耗!');
        }
        return NetError(net_error, '網(wǎng)絡(luò)異常,請檢查你的網(wǎng)絡(luò)谜喊!');
      } else if (error.type == DioErrorType.CONNECT_TIMEOUT ||
          error.type == DioErrorType.SEND_TIMEOUT ||
          error.type == DioErrorType.RECEIVE_TIMEOUT) {
        //  連接超時 || 請求超時 || 響應(yīng)超時
        return NetError(timeout_error, '連接超時潭兽!');
      } else if (error.type == DioErrorType.CANCEL) {
        return NetError(cancel_error, '取消請求');
      } else {
        return NetError(unknown_error, '未知異常');
      }
    } else {
      return NetError(unknown_error, '未知異常');
    }
  }



}

class NetError {
  int code;
  String msg;

  NetError(this.code, this.msg);
}

http_utils

import 'package:jh_flutter_demo/jh_common/widgets/jh_progress_hud.dart';

import 'apis.dart';
import 'dio_utils.dart';
import 'log_utils.dart';

typedef Success<T> = Function(T data);
typedef Fail = Function(int code);

class HttpUtils {
  //登錄
  static void login<T>(
    parameters, {
    Success success,
    Fail fail,
  }) {
//    DioUtils.request(Method.POST, APIs.login, parameters,
//        success: success, fail: fail);
    post(APIs.login, parameters, success: success, fail: fail);
  }

  //分頁加載數(shù)據(jù)
  static void getNewPageList<T>(
    parameters, {
    Success success,
    Fail fail,
  }) {
    post(APIs.getPage, parameters, success: success, fail: fail);
  }

  //GET
  static void GetRequest<T>(
    APIType apiType,
    parameters, {
    Success success,
    Fail fail,
  }) {
    post(APITypeValues[apiType], parameters, success: success, fail: fail);
  }

  //POST
  static void PostRequest<T>(
    APIType apiType,
    parameters, {
    Success success,
    Fail fail,
  }) {
    post(APITypeValues[apiType], parameters, success: success, fail: fail);
  }

  /********************************* 分割線 ********************************/

  //get 請求
  static void get<T>(
    String url,
    parameters, {
    Success success,
    Fail fail,
  }) {
    _request(Method.GET, url, parameters, success: success, fail: fail);
  }

  //post 請求
  static void post<T>(
    String url,
    parameters, {
    Success success,
    Fail fail,
  }) {
    _request(Method.POST, url, parameters, success: success, fail: fail);
  }

  //_request 請求
  static void _request<T>(
    Method method,
    String url,
    parameters, {
    Success success,
    Fail fail,
  }) {
    /// restful 請求處理
    /// /base/search/hist/:user_id        user_id=27
    /// 最終生成 url 為     /base/search/hist/27
    parameters.forEach((key, value) {
      if (url.indexOf(key) != -1) {
        url = url.replaceAll(':$key', value.toString());
      }
    });
//    //參數(shù)處理
//    LogUtils.d("--------- parameters ---------");
//    LogUtils.d("$parameters");

    DioUtils.request(method, url, parameters, success: (result) {
//      LogUtils.d("--------- response ---------");
//      LogUtils.d('$result');
//      LogUtils.print_(result);
      if (result['code'] == 200) {
        if (success != null) {
          success(result);
        }
      } else {
        //其他狀態(tài),彈出錯誤提示信息
        JhProgressHUD.showText(result['msg']);
      }
    }, fail: (code, msg) {
      JhProgressHUD.showError(msg);
      if (fail != null) {
        fail(code);
      }
    });
  }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末斗遏,一起剝皮案震驚了整個濱河市山卦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌诵次,老刑警劉巖账蓉,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異藻懒,居然都是意外死亡,警方通過查閱死者的電腦和手機视译,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門嬉荆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人酷含,你說我怎么就攤上這事鄙早。” “怎么了椅亚?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵限番,是天一觀的道長。 經(jīng)常有香客問我呀舔,道長弥虐,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任媚赖,我火速辦了婚禮霜瘪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘惧磺。我一直安慰自己颖对,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布磨隘。 她就那樣靜靜地躺著缤底,像睡著了一般顾患。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上个唧,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天江解,我揣著相機與錄音,去河邊找鬼坑鱼。 笑死膘流,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的鲁沥。 我是一名探鬼主播呼股,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼画恰!你這毒婦竟也來了彭谁?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤允扇,失蹤者是張志新(化名)和其女友劉穎缠局,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體考润,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡狭园,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了糊治。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片唱矛。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖井辜,靈堂內(nèi)的尸體忽然破棺而出绎谦,到底是詐尸還是另有隱情,我是刑警寧澤粥脚,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布窃肠,位于F島的核電站,受9級特大地震影響刷允,放射性物質(zhì)發(fā)生泄漏冤留。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一树灶、第九天 我趴在偏房一處隱蔽的房頂上張望搀菩。 院中可真熱鬧,春花似錦破托、人聲如沸肪跋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽州既。三九已至谜洽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間吴叶,已是汗流浹背阐虚。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蚌卤,地道東北人实束。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像逊彭,于是被迫代替她去往敵國和親咸灿。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,614評論 2 353