Flutter怎么搭建一套健壮可靠的网络框架
网络框架的搭建
所需依赖库
dio: ^4.0.0 # 网络框架
connectivity: ^3.0.6 # 网络框架相关
crypto: ^3.0.1 #加密库
具体实现
NetBaseRequest类对外暴露的方法
abstract class NetBaseRequest{
request(NetData data);
download(NetData data,{Function(int,int)? progressCallback});
upload(NetData data,{Function(int,int)? sendProgressCallback});
cancelRequest({NetCancelToken? token});
}
对NetBaseRequest类方法的具体实现
class NetRequest extends NetBaseRequest {
late Dio dio;
late NetCancelToken _cancelToken;
NetRequest() {
dio = Dio();
_cancelToken = NetCancelToken();
dio.interceptors.add(NetCommonInterceptor());
dio.interceptors.addAll(NetWorkManger().interceptors);
if (NetWorkManger().isPrintLog) {
dio.interceptors.add(LogInterceptor(
requestBody: true,
responseBody: true,
logPrint: (value) {
print(value);
}));
(dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (HttpClient client) {
client.badCertificateCallback = (X509Certificate cert, String host, int port) =>true;
return client;
};
}
}
///下载
@override
Future<NetData> download(NetData data,
{Function(int, int)? progressCallback}) async {
dio.options = _initOptions(data);
Response response = await dio.download(data.url, data.downloadFilePath,
cancelToken: data.cancelToken ?? _cancelToken,
queryParameters: data.params,
onReceiveProgress: progressCallback);
return _responseData(data, response);
}
BaseOptions _initOptions(NetData data) {
BaseOptions baseOptions = BaseOptions();
baseOptions.contentType = data.contentType;
baseOptions.connectTimeout = data.connectTimeOut;
baseOptions.receiveTimeout = data.readTimeout;
baseOptions.headers = data.header;
baseOptions.responseType = ResponseType.json;
_addDioProxy(data);
return baseOptions;
}
@override
Future<NetData> request(NetData data) async {
dio.options = _initOptions(data);
try {
switch (data.requestType) {
case RequestType.GET:
return await _requestGet(data);
case RequestType.POST:
return await _requestPost(data);
}
} on DioError catch (e) {
var response = e.response;
if (response != null) {
if (response.data != null) {
data.resultStatus = ResultStatus.success;
data.resultData = response.data;
NetWorkManger().responseInterceptor?.responseInterceptor(data);
return data;
}
}
_requestError(data);
return data;
}
}
///get网络请求
_requestGet(NetData data) async {
Response response;
if (data.params == null) {
response = await dio.get(data.url,
cancelToken: data.cancelToken ?? _cancelToken);
} else {
response = await dio.get(data.url,
queryParameters: data.params,
cancelToken: data.cancelToken ?? _cancelToken);
}
return _responseData(data, response);
}
///post网络请求
_requestPost(NetData data) async {
Response response;
if (data.params == null) {
response = await dio.post(data.url,
cancelToken: data.cancelToken ?? _cancelToken);
} else {
response = await dio.post(data.url,
data: data.params, cancelToken: data.cancelToken ?? _cancelToken);
}
return _responseData(data, response);
}
///文件上传
@override
upload(NetData data, {Function(int, int)? sendProgressCallback}) async {
dio.options = _initOptions(data);
if (data.uploadMap.isNotEmpty) {
data.resultStatus = ResultStatus.processing;
Map<String, dynamic> fileMap = {};
data.uploadMap.forEach((key, value) {
fileMap[key] =
MultipartFile.fromFile(value, filename: getFileName(value));
});
FormData formData = FormData.fromMap(fileMap);
Response response = await dio.post(data.url,
data: formData,
queryParameters: data.params,
onSendProgress: sendProgressCallback,
cancelToken: data.cancelToken ?? _cancelToken);
return _responseData(data, response);
}
}
///返回数据解析
_responseData(NetData data, Response response) {
try {
if (response.statusCode == 200) {
data.resultStatus = ResultStatus.success;
data.resultData = response.data;
// data.rootBean = NetResponseBean.fromJson(response.data);
} else {
_requestError(data);
}
} catch (e) {
_requestError(data);
}
//拦截器处理
NetWorkManger().responseInterceptor?.responseInterceptor(data);
return data;
}
///添加网络代理,用于抓包
_addDioProxy(NetData data) {
try {
if (data.isSetProxy &&
data.proxyPort.isNotEmpty &&
data.proxyIp.isNotEmpty) {
(dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
(HttpClient client) {
client.findProxy = (uri) {
return "PROXY ${data.proxyIp}:${data.proxyPort}";
};
client.badCertificateCallback =
(X509Certificate cert, String host, int port) => true;
return null;
};
}
} catch (e) {
print(e);
}
}
@override
cancelRequest({NetCancelToken? token}) {
CancelToken _token = token ?? _cancelToken;
_token.cancel();
}
_requestError(NetData data) {
data.resultStatus = ResultStatus.serviceError;
NetResponseBean root = NetResponseBean();
root.success = "false";
root.code = "-10001";
root.msg = "网络异常,请稍后重试!";
data.rootBean = root;
}
Future<bool> isConnected() async {
var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.mobile) {
// I am connected to a mobile network.
return true;
} else if (connectivityResult == ConnectivityResult.wifi) {
// I am connected to a wifi network.
return true;
}
return false;
}
String getFileName(String filePath) {
if (filePath.isEmpty || !filePath.contains("/")) {
return "";
}
return filePath.substring(filePath.lastIndexOf("/") + 1, filePath.length);
}
}
配置参数NetData
class NetData {
RequestType requestType = RequestType.POST; //请求类型
Map<String, dynamic>? params; //参数
Map<String, dynamic> header = NetWorkManger().header; //请求头
String url = ""; //请求地址
String baseUrl = "";
NetCancelToken? cancelToken;
///上传,key是上传的key ,value是文件地址
Map<String, String> uploadMap = {};
///下载储存文件的地址
String downloadFilePath = '';
int connectTimeOut = NetWorkManger().connectTimeOut; //连接超时时间:默认30秒
int readTimeout = NetWorkManger().readTimeout; //读取超时时间:默认30秒
String contentType = NetWorkManger().contentType; //http
String proxyIp = NetWorkManger().proxyIp; //代理ip
String proxyPort = NetWorkManger().proxyPort; //代理端口
bool isSetProxy = NetWorkManger().isSetProxy; //是否开启代理
//以下为返回数据
ResultStatus? resultStatus; //请求状态
dynamic resultData; //返回数据
RequestType resultType = RequestType.POST; //解析
NetBaseBean rootBean = NetResponseBean(); //解析bean 默认是rootBean 可以设置
bool isEncryption = false; //参数,返回值是否加解密
bool isShowLoading = false; //是否显示加载loading弹窗
bool isSuccess() {
return rootBean.isSuccess();
}
}
网络框架的使用
参数说明
url 接口地址
type 请求方式
param 请求参数
token 删除请求token,new NetCanceToken即可使用
isEncryption 是否加密
isShowLoading 是否显示加载弹窗
success 成功,返回参数仅只是data数据,不包含code和msg
error 失败,参数返回code和msg
req(String url,
{RequestType type = RequestType.POST,
Map<String, dynamic>? param,
NetCancelToken? token,
bool isEncryption = false,
bool isShowLoading = true,
Function? success,
Function? error}) {}
继承调用方式
填空法
用填空的方式设置请求参数
继承BaseRequest<T>实现 T为返回data实体对象的类型
initApiUrl() 设置->url
addParam(String key, dynamic value) 设置->param
addParams(Map<String, dynamic> map) 设置->params
initReqType() 设置->get or post
jsonToData() 设置-> 填jsonData解析成T类型的方法
剩下参数 isEncryption isShowLoading等 需要更改可以在继承类中直接重写
调用
TestRequest req = TestRequest();
req.addParam("key", "value");
req.req((data){ 成功返回T->data }, (code, msg) {失败code msg });
例子参考
class LoginRequest extends BaseRequest<User> {
@override
String initApiUrl() {
return "http://xxxxx";
}
@override
RequestType initReqType() {
return RequestType.GET;
}
@override
User jsonToData(Map<String, dynamic> jsonData) {
return User.fromJson(jsonData);
}
}
post调用
NetUtils().req("",
param: {},
success: (success){},
error: (code,msg){});
get调用
NetUtils().req("",
type = RequestType.GET,
param: {},
success: (success){},
error: (code,msg){});
#### 数据返回获取更多的信息
NetUtils().requestCommon("",
RequestType.GET,
param: {}).then((value){
//TODO value是NetData,rootBean中包含接口返回的信息code,msg data
});
上传
参数说明
url上传地址
uploadMap 参数
token 删除请求token,new NetCanceToken即可使用
sendProgressCallback 上传进度
isShowloading 是否显示加载弹框
success 成功
fail 失败
调用
NetUtils().requestUploadFile(String url,
Map<String,String> uploadMap,
{NetCancelToken? token,
Function(int, int)? sendProgressCallback,
bool isShowloading = true,
ValueChanged? success,
ValueChanged? fail}) {}
下载
参数说明
url上传地址
filePath 储存路劲 ��
param 参数
token 删除请求token,new NetCanceToken即可使用
progressCallback 下载进度
isShowloading 是否显示加载弹框
success 成功
fail 失败
调用
requestDownLoading(String url,
String filePath,
{Map<String, dynamic>? param,
NetCancelToken? token,
Function(int, int)? progressCallback,
bool isShowloading = true,
ValueChanged? success,
ValueChanged? fail}) {}
网友评论