一、添加依赖
dio: ^5.3.2
二、请求封装
class HttpHelper {
static Dio? mDio;
static BaseOptions? options;
static HttpHelper? httpHelper;
CancelToken cancelToken = CancelToken();
static const String GET = 'get';
static const String POST = 'post';
static const String PUT = 'put';
static const String PATCH = 'patch';
static const String DELETE = 'delete';
static HttpHelper? get instance => getInstance();
static Dio? get dio => getDio();
static HttpHelper? getInstance() {
httpHelper ??= HttpHelper();
return httpHelper;
}
static Dio? getDio() {
final token = GetStorage().read('token');
final Map<String, dynamic> headerMap = {};
if (token != null) {
headerMap.putIfAbsent("Authorization", () => "Bearer $token");
}
options = BaseOptions(
baseUrl: Api.BASE_URL,
connectTimeout: const Duration(seconds: 10),
receiveTimeout: const Duration(seconds: 5),
headers: headerMap,
contentType: Headers.jsonContentType,
responseType: ResponseType.json,
);
mDio = Dio(options);
mDio?.interceptors.add(interceptorsWrapper());
mDio?.httpClientAdapter = IOHttpClientAdapter(
createHttpClient: () {
final client = HttpClient();
client.findProxy = (uri) {
return 'PROXY 192.168.0.191:8089';
};
return client;
},
);
return mDio;
}
static InterceptorsWrapper interceptorsWrapper() {
return InterceptorsWrapper(onRequest: (options, handler) {
return handler.next(options);
}, onResponse: (response, handler) {
return handler.next(response);
}, onError: (DioError e, handler) {
if (e.response != null) {
if (e.response?.statusCode == 401) {
ToastMsg.show("当前登录已过期,请重新登录!");
Future.delayed(const Duration(milliseconds: 1000), () {
Get.offAllNamed(AppRoutes.LOGIN);
});
} else if (e.response?.statusCode == 403) {
ToastMsg.show("暂无权限访问,请联系管理员!");
} else {
ToastMsg.show("系统内部异常!");
}
}
return handler.next(e);
});
}
Future<BaseRes<T>> getHttp<T>(String url, parameters,{loading = true}) async {
return await getResponse<T>(url, method: GET, parameters: parameters,loading:loading);
}
Future<BaseRes<T>> postHttp<T>(String url, parameters,{loading = true}) async {
parameters = parameters ?? <String, dynamic>{};
return await getResponse<T>(url, method: POST, parameters: parameters,loading:loading);
}
Future<BaseRes<T>> putHttp<T>(String url, parameters,{loading = true}) async {
parameters = parameters ?? <String, dynamic>{};
return await getResponse<T>(url, method: PUT, parameters: parameters,loading:loading);
}
Future<BaseRes<T>> deleteHttp<T>(String url, parameters,{loading = true}) async {
parameters = parameters ?? <String, dynamic>{};
return await getResponse<T>(url, method: DELETE, parameters: parameters,loading:loading);
}
downloadFile(urlPath, savePath, onReceiveProgress) async {
Response? response;
try {
response = await dio?.download(urlPath, savePath,
onReceiveProgress: onReceiveProgress);
} on DioError catch (e) {
formatError(e);
}
return response?.data;
}
Future<BaseRes<T>> getResponse<T>(
String url, {
required String method,
parameters,
loading,
}) async {
Response<Map<String, dynamic>>? response;
if(loading) {
ToastMsg.showLoading();
}
switch (method) {
case GET:
response = await dio?.get(url,
queryParameters: parameters ?? <String, dynamic>{});
break;
case PUT:
response = await dio?.put(url,
queryParameters: parameters ?? <String, dynamic>{});
break;
case DELETE:
response = await dio?.delete(url,
queryParameters: parameters ?? <String, dynamic>{});
break;
default:
response =
await dio?.post(url, data: parameters ?? <String, dynamic>{});
break;
}
if(loading) {
ToastMsg.cancelLoading();
}
if (response?.statusCode == 200) {
BaseRes<T> bean = BaseRes.fromJson(response?.data);
return bean;
} else if (response?.statusCode == 401) {
ToastMsg.show("当前登录已过期,请重新登录!");
Future.delayed(const Duration(milliseconds: 1000), () {
Get.offAllNamed(AppRoutes.LOGIN);
});
} else if (response?.statusCode == 403) {
ToastMsg.show("暂无权限访问,请联系管理员!");
} else {
ToastMsg.show("系统内部异常!");
}
throw Exception('${response?.statusCode}+${response?.statusMessage}');
}
void formatError(DioError e) {
print(e.message);
}
void cancelRequests(CancelToken token) {
token.cancel("cancelled");
}
}
三、封装统一返回类
@JsonSerializable()
class BaseRes<T>{
BaseRes(this.msg, this.code, this.data);
late String msg;
late int code;
late T data;
BaseRes.fromJson(Map<String, dynamic>? json) {
if (json?['data'] != null && json?['data'] != 'null') {
data = JsonConvert.fromJsonAsT<T>(json?['data']) as T;
}
msg = json?['msg'];
code = json?['code'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
if (this.data != null) {
data['data'] = this.data;
}
data['code'] = this.code;
data['msg'] = this.msg;
return data;
}
}
四、使用
BaseRes<UserInfoEntity>? res = await HttpHelper.instance?.getHttp(Api.GET_USER_INGO,null,loading: false);
if(res?.code == 200 && res?.data != null) {
state.userInfo = res!.data.obs;
}