【开源鸿蒙Flutter跨平台开发学习笔记 】DAY05:实现Axios网络请求封装 & 代码上传到GitCode仓库
·
一、接上篇,实现Axios实现的网络封装。
昨天已经封装了BaseHttpClient,Axios只需要继承BaseHttpClient即可,代码实现如下:
import 'package:dio/dio.dart';
import 'package:flutter_axios/flutter_axios.dart' hide Interceptor, ProgressCallback;
import 'base_http_client.dart';
import 'config/api_config.dart';
import 'exceptions/app_exceptions.dart';
import 'models/api_response.dart';
class AxiosHttpClient extends BaseHttpClient {
late AxiosInstance _api;
String _baseUrl = ApiConfig.baseUrl;
Map<String, String> _headers = ApiConfig.defaultHeaders;
Duration _connectTimeout = ApiConfig.connectTimeout;
Duration _receiveTimeout = ApiConfig.receiveTimeout;
Duration _sendTimeout = ApiConfig.sendTimeout;
AxiosHttpClient() {
_initAxios();
}
void _initAxios() {
_api = Axios.create(
AxiosConfig(
baseURL: _baseUrl,
timeout: _connectTimeout,
headers: _headers,
),
);
}
@override
void setBaseUrl(String baseUrl) {
_baseUrl = baseUrl;
_initAxios();
}
@override
void setHeaders(Map<String, String> headers) {
_headers = {..._headers, ...headers};
_initAxios();
}
@override
void setTimeout(Duration connectTimeout, Duration receiveTimeout, Duration sendTimeout) {
_connectTimeout = connectTimeout;
_receiveTimeout = receiveTimeout;
_sendTimeout = sendTimeout;
_initAxios();
}
@override
void addInterceptor(Interceptor interceptor) {}
@override
void removeInterceptor(Interceptor interceptor) {}
@override
void clearInterceptors() {}
@override
Future<ApiResponse<T>> get<T>(
String path, {
Map<String, dynamic>? queryParameters,
Options? options,
String? requestId,
}) async {
return _executeRequest<T>(
() async => await _api.get(_buildUrl(path, queryParameters)),
);
}
@override
Future<ApiResponse<T>> post<T>(
String path, {
dynamic data,
Map<String, dynamic>? queryParameters,
Options? options,
String? requestId,
}) async {
return _executeRequest<T>(
() async => await _api.post(_buildUrl(path, queryParameters), data: data),
);
}
@override
Future<ApiResponse<T>> put<T>(
String path, {
dynamic data,
Map<String, dynamic>? queryParameters,
Options? options,
String? requestId,
}) async {
return _executeRequest<T>(
() async => await _api.put(_buildUrl(path, queryParameters), data: data),
);
}
@override
Future<ApiResponse<T>> delete<T>(
String path, {
dynamic data,
Map<String, dynamic>? queryParameters,
Options? options,
String? requestId,
}) async {
return _executeRequest<T>(
() async => await _api.delete(_buildUrl(path, queryParameters)),
);
}
@override
Future<ApiResponse<T>> patch<T>(
String path, {
dynamic data,
Map<String, dynamic>? queryParameters,
Options? options,
String? requestId,
}) async {
return _executeRequest<T>(
() async => await _api.patch(_buildUrl(path, queryParameters), data: data),
);
}
@override
void cancelRequest(String requestId) {}
@override
void cancelAllRequests() {}
@override
Future<ApiResponse<T>> upload<T>(
String path, {
required String filePath,
required String fileKey,
Map<String, dynamic>? data,
ProgressCallback? onSendProgress,
Options? options,
String? requestId,
}) async {
throw UnimplementedError();
}
@override
Future<ApiResponse<T>> download<T>(
String path, {
required String savePath,
ProgressCallback? onReceiveProgress,
Map<String, dynamic>? queryParameters,
Options? options,
String? requestId,
}) async {
return _executeRequest<T>(
() async => await _api.get(_buildUrl(path, queryParameters)),
);
}
@override
void setAuthToken(String token) {
_headers = {..._headers, 'Authorization': 'Bearer $token'};
_initAxios();
}
@override
void clearAuthToken() {
_headers = Map.from(_headers)..remove('Authorization');
_initAxios();
}
@override
bool isNetworkError(DioException error) {
return error.type == DioExceptionType.connectionTimeout ||
error.type == DioExceptionType.sendTimeout ||
error.type == DioExceptionType.receiveTimeout ||
error.type == DioExceptionType.connectionError ||
error.type == DioExceptionType.unknown;
}
@override
bool isServerError(int statusCode) {
return statusCode >= 500 && statusCode < 600;
}
@override
void dispose() {}
String _buildUrl(String path, Map<String, dynamic>? query) {
if (query == null || query.isEmpty) return path;
final uri = Uri(path: path, queryParameters: query.map((k, v) => MapEntry(k, v?.toString())));
return uri.toString();
}
Future<ApiResponse<T>> _executeRequest<T>(
Future<AxiosResponse> Function() request,
) async {
try {
final response = await request();
final data = response.data as T;
final headers = response.headers;
final status = response.status;
return ApiResponse.success(
data,
statusCode: status ?? 200,
headers: headers,
);
} catch (e) {
throw _handleAxiosError(e);
}
}
AppException _handleAxiosError(Object error) {
final msg = error.toString();
if (msg.contains('Timeout')) {
return TimeoutException('请求超时,请检查网络连接');
}
if (msg.contains('Network') || msg.contains('Socket')) {
return NetworkException('网络连接失败,请检查网络设置');
}
if (msg.contains('401')) {
return AuthenticationException('身份验证失败');
}
if (msg.contains('404')) {
return ServerException('资源未找到', 404);
}
return UnknownException('未知错误: $msg');
}
}
使用的时候只需要把HttpClient替换成AxiosHttpClient即可
效果如下:

关于网络请求的封装暂时告一个段落,还有一些问题暂时没时间解决,比如网络请求涉及到的Interceptor、Exception、Options等用的都是Dio库的类,自己并没有单独处理,这导致axios仅仅实现了HttpClient,并没有完全脱离Dio,有时间再优化。
二、代码上传到GitCode仓库
1、在 GitCode 上创建新仓库
地址:https://gitcode.com/create?position=nav_top

2、在本地项目初始化 Git(如果尚未初始化)
@@@ pocket % git init
Initialized empty Git repository in /Users/xxxxx/Desktop/flutter/pocket/.git/
3、将本地仓库与 GitCode 远程仓库关联
git remote add origin https://gitcode.com/xiaoyuxia/gitcode-pocket.git
4、添加文件、提交更改
git add .
5、推送到 GitCode
推送前拉一下仓库:
git pull origin main
commit:
git commit -m "initial commit"
push:
git push -u origin main:main
https://gitcode.com/xiaoyuxia/gitcode-pocket 如下:

😁,代码已上传到GitCode仓库,需要的可以点击此处下载
更多推荐


所有评论(0)