引言
flutter网络请求我们使用dio库来实现:
dependencies:
flutter:
sdk: flutter
dio: ^3.0.10
一个基础网络库,通常我们将其分成两个部分:
- 基础网络层
- 数据模型转换层
那今天,我们先来实现基础网络层的功能封装
新建 base_request.dart 文件,封装requestOptions,并对外提供内容注入能力(子类重写):
typedef ProgressCallback = void Function(int count, int total);
abstract class BaseRequest {
String get path;
String get method => 'POST';
int get connectTimeout => 5000;
int get receiveTimeout => 5000;
int get sendTimeout => 5000;
Map get headers => null;
ProgressCallback get onReceiveProgress => null;
bool get showErrorToast => true;
RequestOptions requestOptions() {
return RequestOptions(
path: path,
method: method,
connectTimeout: connectTimeout,
receiveTimeout: receiveTimeout,
sendTimeout: sendTimeout,
cancelToken: cancelToken,
headers: headers,
onReceiveProgress: onReceiveProgress,
responseType: ResponseType.json,
extra: {
'showErrorToast': showErrorToast,
},
);
}
}
在基类上面再封装一层,用于抽象具体的请求方法:
abstract class BaseJsonRequest with BaseRequest {
//dio 需要调用者注入进来
Dio get dio;
Set get successCodes => {0};
Future request() async {
try {
final response = await dio.request
该工具类不能直接使用,需要被具体业务方继承使用,path不能为空
业务数据结构模型,统一接口返回的数据结构
class _ResponsBaseModel {
int code;
String message;
dynamic data;
Set successCodes;
PDResponsBaseModel({
this.code,
this.data,
this.message,
this.successCodes,
});
bool get success => successCodes != null && successCodes.contains(code);
factory _PDResponsBaseModel.fromMap(
Map map,
Set successCodes,
) {
return _PDResponsBaseModel(
code: (map['code'] as int) ?? -1,
message: (map['message'] as String) ?? '',
data: map['data'],
successCodes: successCodes,
);
}
}
具体使用时这么用:
新建一个类用于继承BaseJsonRequest,业务方直接调用execute方法进行网络请求,返回结构为数据模型实例
class MemberInfoRequest extends BaseJsonRequest {
final String identity;
MemberInfoRequest(this.identity);
@override
String get path => '/getMemberInfo';
@override
Dio get dio => Dio(); //dio可自行封装成全局单例工具类,并在初始化时添加拦截器等
@override
get data => {'identity': identity, 'identityType': 3};
@override
Future execute() {
return request().then((value) {
return MemberInfo.fromJson(value.mapData);
});
}
}
拦截器怎么写?
class LoggingInterceptor extends Interceptor {
LoggingInterceptor();
@override
Future onRequest(RequestOptions options) {
//options.data 进行入参插入操作
return Future.value(options);
}
@override
Future onResponse(Response response) {
return Future.value(response);
}
@override
Future onError(DioError err) async {
return err;
}
}
//将拦截器设置给dio实例
dio.interceptors.addAll([LoggingInterceptor()]);