# dio_enterprise_demo **Repository Path**: vper/dio_enterprise_demo ## Basic Information - **Project Name**: dio_enterprise_demo - **Description**: No description available - **Primary Language**: Dart - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 4 - **Created**: 2025-11-30 - **Last Updated**: 2025-12-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Dio 企业级 Demo 一个基于 Flutter 和 Dio 的企业级 HTTP 客户端示例项目,演示了 Token 自动刷新、错误处理、拦截器等企业级功能。 ## 🚀 项目特性 - ✅ **Token 自动刷新** - 处理 401 错误并自动刷新 Token - ✅ **拦截器机制** - 请求/响应/错误拦截器完整实现 - ✅ **单例模式** - API 服务使用单例模式管理 - ✅ **异常处理** - 统一的异常处理机制 - ✅ **日志记录** - 完整的请求/响应日志 - ✅ **超时配置** - 可配置的连接和接收超时 ## 📁 项目结构 ``` lib/ ├── api/ │ ├── api_service.dart # API 服务类(单例模式) │ ├── token_manager.dart # Token 管理器 │ ├── token_refresh_interceptor.dart # Token 刷新拦截器 │ └── app_exception.dart # 应用异常类 ├── pages/ │ └── home_page.dart # 主页组件 └── main.dart # 应用入口 ``` ## 🛠️ 技术栈 - **Flutter** - 跨平台移动应用框架 - **Dio** - 强大的 Dart HTTP 客户端 - **Material Design** - Google 设计语言 ## 📦 依赖项 在 `pubspec.yaml` 中配置的依赖: ```yaml dependencies: flutter: sdk: flutter dio: ^5.9.0 # HTTP 客户端 go_router: ^17.0.0 # 路由管理 cupertino_icons: ^1.0.8 ``` ## 🏃‍♂️ 快速开始 ### 1. 克隆项目 ```bash git clone cd dio_enterprise_demo ``` ### 2. 安装依赖 ```bash flutter pub get ``` ### 3. 运行应用 ```bash flutter run ``` ## 🔧 核心功能详解 ### API 服务类 (`api_service.dart`) 使用单例模式管理 Dio 实例,配置基础选项和拦截器: ```dart class ApiService { static final ApiService _instance = ApiService._internal(); late Dio dio; factory ApiService() => _instance; ApiService._internal() { dio = Dio(BaseOptions( baseUrl: "https://httpbin.org/", connectTimeout: const Duration(seconds: 10), receiveTimeout: const Duration(seconds: 10), )); dio.interceptors.add(TokenRefreshInterceptor()); dio.interceptors.add(LogInterceptor(requestBody: true, responseBody: true)); } } ``` ### Token 刷新拦截器 (`token_refresh_interceptor.dart`) 核心功能:处理 401 错误并自动刷新 Token: ```dart class TokenRefreshInterceptor extends Interceptor { bool _isRefreshing = false; Completer? _refreshCompleter; @override void onError(DioException err, ErrorInterceptorHandler handler) async { // 只处理 401 错误 if (err.response?.statusCode == 401) { if (!_isRefreshing) { _isRefreshing = true; _refreshCompleter = Completer(); try { final newToken = await TokenManager.refreshToken(); _refreshCompleter?.complete(newToken); } catch (e) { _refreshCompleter?.complete(null); } finally { _isRefreshing = false; } } // 等待刷新结果并重试请求 final newToken = await _refreshCompleter!.future; // ... 重试逻辑 } } } ``` ### Token 管理器 (`token_manager.dart`) 模拟 Token 存储和刷新功能: ```dart class TokenManager { static String? _token = "initial_token"; static Future getToken() async { return _token; } static Future refreshToken() async { print("🔄 模拟刷新 Token..."); await Future.delayed(const Duration(seconds: 2)); _token = "token_${DateTime.now().millisecondsSinceEpoch}"; print("✅ 刷新成功:$_token"); return _token; } } ``` ## 🧪 测试功能 ### 模拟 401 错误测试 在 `home_page.dart` 中,你可以切换注释来测试不同场景: ```dart // 模拟 401 错误(Token 过期) final res = await ApiService().get("/status/401"); // 模拟成功请求 final res = await ApiService().get("/status/200"); ``` ### 测试流程 1. **正常请求** - 使用 `/status/200` 测试成功场景 2. **Token 过期** - 使用 `/status/401` 测试自动刷新机制 3. **观察日志** - 查看控制台输出的请求/响应日志 ## 📱 界面展示 应用包含一个简单的主页,包含: - **应用栏** - 显示应用标题 - **测试按钮** - 触发 HTTP 请求测试 - **SnackBar 提示** - 显示请求结果 ## 🔄 工作流程 ### Token 自动刷新流程 1. **发送请求** → 携带当前 Token 2. **收到 401 响应** → Token 过期 3. **启动刷新流程** → 调用 `TokenManager.refreshToken()` 4. **等待刷新完成** → 其他请求排队等待 5. **刷新成功** → 使用新 Token 重试原请求 6. **刷新失败** → 抛出 Token 过期异常 ### 防止重复刷新 使用 `_isRefreshing` 标志位确保同一时间只有一个刷新请求: ```dart if (!_isRefreshing) { _isRefreshing = true; // 执行刷新逻辑 } ``` ## 🚨 错误处理 ### 异常类型 项目定义了三种异常类型: ```dart enum ExceptionType { NetworkError, // 网络错误 TokenExpired, // Token 过期 Unknown // 未知错误 } ``` ### 统一异常处理 所有异常都封装为 `AppException`: ```dart class AppException implements Exception { final ExceptionType type; final String message; AppException(this.type, this.message); @override String toString() => "AppException: $message"; } ``` ## 🔧 配置说明 ### 基础 URL 配置 在 `api_service.dart` 中可以切换测试服务器: ```dart // 用于模拟 401 错误的服务器 baseUrl: "https://httpstat.us", // 用于模拟 Token 刷新场景的服务器 baseUrl: "https://httpbin.org/", ``` ### 超时配置 ```dart connectTimeout: const Duration(seconds: 10), // 连接超时 receiveTimeout: const Duration(seconds: 10), // 接收超时 ``` ## 📈 性能优化建议 1. **Token 缓存** - 实际项目中应持久化存储 Token 2. **刷新频率限制** - 防止频繁刷新导致的性能问题 3. **请求队列管理** - 优化大量并发请求的处理 4. **网络状态检测** - 添加网络连接状态检查 ## 🤝 贡献指南 欢迎提交 Issue 和 Pull Request 来改进这个项目! ## 📄 许可证 本项目采用 MIT 许可证 - 查看 [LICENSE](LICENSE) 文件了解详情。 ## 🙏 致谢 - [Dio](https://pub.dev/packages/dio) - 优秀的 Dart HTTP 客户端 - [Flutter](https://flutter.dev) - Google 的跨平台 UI 工具包 --- **开发愉快!🚀**