Flutter 通用API调用类/方法(GET/POST等)实现示例咨询
Flutter 通用API请求封装实现示例
我们通常基于dio网络库实现通用请求封装,以下是可直接复用的实现方案,支持统一异常拦截、统一请求头注入、GET/POST/PUT/DELETE等全请求类型适配:
第一步:添加依赖
在pubspec.yaml中引入dio依赖:
dependencies: dio: ^5.4.0 # 可替换为最新稳定版
第二步:通用请求类实现
import 'package:dio/dio.dart'; class ApiClient { // 单例实例,避免重复初始化 static final ApiClient _instance = ApiClient._internal(); factory ApiClient() => _instance; ApiClient._internal() { _initDio(); } late final Dio _dio; final String _baseUrl = 'https://你的API基础地址/'; // 初始化基础配置 void _initDio() { _dio = Dio(BaseOptions( baseUrl: _baseUrl, connectTimeout: const Duration(seconds: 15), receiveTimeout: const Duration(seconds: 15), headers: { 'Content-Type': 'application/json; charset=utf-8', // 可在此添加通用固定请求头 }, )); // 统一拦截器配置 _dio.interceptors.add(InterceptorsWrapper( onRequest: (options, handler) { // 统一注入动态请求头,例如用户token // String? token = 你的全局token获取逻辑(); // if (token != null) options.headers['Authorization'] = 'Bearer $token'; return handler.next(options); }, onResponse: (response, handler) { // 统一处理业务状态码,例如token过期跳转登录 // if (response.data['code'] == 401) { // 全局跳转登录页逻辑(); // } return handler.next(response); }, onError: (DioException e, handler) { // 统一异常提示,例如网络错误toast弹窗 // String errorMsg = _handleError(e); // 全局toast提示逻辑(errorMsg); return handler.next(e); }, )); } // 通用请求核心方法 Future<T> request<T>( String path, { String method = 'GET', Map<String, dynamic>? queryParams, dynamic data, Options? options, CancelToken? cancelToken, }) async { options ??= Options(); options.method = method; try { final response = await _dio.request( path, queryParameters: queryParams, data: data, options: options, cancelToken: cancelToken, ); // 可根据后端返回格式统一解析,直接返回业务数据 // 示例:后端返回格式为{code:xxx, msg:xxx, data:xxx}时,直接返回data字段 // return response.data['data'] as T; return response.data as T; } on DioException catch (e) { throw _handleError(e); } catch (e) { throw '未知错误:${e.toString()}'; } } // 异常格式化处理 String _handleError(DioException e) { switch (e.type) { case DioExceptionType.connectionTimeout: case DioExceptionType.sendTimeout: case DioExceptionType.receiveTimeout: return '网络请求超时,请稍后重试'; case DioExceptionType.badResponse: final statusCode = e.response?.statusCode; if (statusCode == 400) return '请求参数错误'; if (statusCode == 401) return '登录已过期,请重新登录'; if (statusCode == 403) return '暂无权限访问该资源'; if (statusCode == 404) return '请求的资源不存在'; if (statusCode == 500) return '服务器内部错误'; return '服务器错误,状态码:$statusCode'; case DioExceptionType.cancel: return '请求已取消'; case DioExceptionType.unknown: default: return '网络异常,请检查网络设置后重试'; } } // 快捷GET请求 Future<T> get<T>( String path, { Map<String, dynamic>? queryParams, Options? options, CancelToken? cancelToken, }) => request( path, method: 'GET', queryParams: queryParams, options: options, cancelToken: cancelToken, ); // 快捷POST请求 Future<T> post<T>( String path, { Map<String, dynamic>? queryParams, dynamic data, Options? options, CancelToken? cancelToken, }) => request( path, method: 'POST', queryParams: queryParams, data: data, options: options, cancelToken: cancelToken, ); // 可按需求扩展put、delete等快捷方法 }
使用示例
// 示例1:GET请求 void fetchUserInfo() async { try { final userInfo = await ApiClient().get<Map>( '/user/info', queryParams: {'userId': 123}, ); // 直接处理业务数据 print('用户信息:$userInfo'); } catch (e) { // 仅需处理业务特殊异常,通用异常已在封装类统一处理 print('请求失败:$e'); } } // 示例2:POST请求 void submitForm() async { try { final result = await ApiClient().post<Map>( '/form/submit', data: {'name': '张三', 'age': 25}, ); print('提交结果:$result'); } catch (e) { print('提交失败:$e'); } }
内容的提问来源于stack exchange,提问作者CHANDUKA SAMARASINGHE.
相关产品推荐
相关产品推荐

