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: 暫時沒有加攔截器
調(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);
}
});
}
}