network
- aes 加解密操作
- entity 基础实体类
- interceptor 拦截器
- http_error 错误码
- net_exception 异常拦截
- vv_net_work 单例的Dio对象
Dio配合Charles 抓包配置,ConstantConfig.localProxy配置本机IP,既可以实现抓包
if (ConstantConfig.localProxy.isNotEmpty) {
(_client.httpClientAdapter as DefaultHttpClientAdapter)
.onHttpClientCreate = (client) {
client.badCertificateCallback =
(X509Certificate cert, String host, int port) {
// if(cert.pem==PEM){ // Verify the certificate
// return true;
// }
return true;
};
client.findProxy = (uri) {
return ConstantConfig.localProxy;
};
};
}
网络取消,结合ViewModel进行取消,具体怎么取消的,记得看源码
static Map<String, CancelToken> cancelTokens = new Map<String, CancelToken>();
///取消请求
static void cancelHttp(String tag) {
if (cancelTokens.containsKey(tag)) {
if (!cancelTokens[tag].isCancelled) {
cancelTokens[tag].cancel();
}
cancelTokens.remove(tag);
}
}
这里有一个比较重要的操作,就是数据解析了。Dart语言没有实际的泛型概念,无法类似Android实体化泛型,所以,这里我们把数据塞进BaseResponseEntity,通过解析 var dynamicData = json.decode(decodeData);来达到业务获取数据
if (baseResult['code'] == HTTP_SUCCEED) {
var data = baseResult['data'];
if (data != null) {
try {
//解密
String decodeData = EncryptUtil.aesDecode(data);
var dynamicData = json.decode(decodeData);
print('解密后的数据$decodeData');
BaseResponseEntity<T> baseResEntity = BaseResponseEntity(
data: dynamicData,
code: baseResult['code'],
msg: baseResult['msg'],
timeStamp: baseResult['timeStamp']);
return new Future.value(baseResEntity);
} catch (e) {
throw (new ResponseException(
code: baseResult['code'],
message: e.toString(),
errorData: baseResult['data']));
}
} else {
throw (new ResponseException(
code: baseResult['code'],
message: baseResult['msg'],
errorData: baseResult['data']));
}
}
通过上述net分析,以及网上大部分人的写法可以知道。使用Dart的时候,解析数据有点小麻烦,Flutter-Habit通过JsonConvert.fromJsonAsT,扩展了一个方法属性,来使业务更加简单
extension NetExtension<T> on Future<BaseResponseEntity<T>> {
Future<T> check() async {
var baseResponseEntity = await this;
return Future.value(JsonConvert.fromJsonAsT<T>(baseResponseEntity.data));
}
}
用法例子如下:
class LoginModel extends BaseModel {
Future<LoginRespEntity> login(LoginReqUserEntity loginReqUserEntity) =>
apiService
.request<LoginRespEntity>(
LoginApiService.loginUrl,
queryParameters: loginReqUserEntity.toJson(),
)
.check();
}
在具体的业务层使用
void toLogin(BuildContext context, String account, String password) {
var loginReqUserEntity = LoginReqUserEntity()
..loginName = "123"
..password = "456"
..organizeType = 3;
launch(() async {
var login = await model.login(loginReqUserEntity);
showToast(login.loginName);
NavigatorUtils.pushNamed(context, PassWordForgetPage.sName);
}, (err) {
});
}
注意,这里对launch的封装,可以全局控制所有异常
void launch(Future<void> Function() future, HttpFailureCallback err,
{bool ignoreToast = false,
bool showLoadingIndicator = false,
bool isCancelable = true}) {
future().catchError((onError) {
///错误所有的网络异常
print("啥错误${onError.toString()}");
err.call(Exception(
HttpError.checkNetError(onError, ignoreToast: ignoreToast)));
});
}
整体的业务结构,比较核心的大概就是这两个地方了。其他的看开源的项目吧。
Flutter-Habit
网友评论