jsp网站开发代码下载wordpress导入txt
jsp网站开发代码下载,wordpress导入txt,网站新媒体建设,wordpress审核认证插件欢迎大家加入[开源鸿蒙跨平台开发者社区](https://openharmonycrossplatform.csdn.net)#xff0c;一起共建开源鸿蒙跨平台生态。
在 Flutter 开发中#xff0c;网络请求是连接前端与后端的 “命脉”。很多开发者初期会直接使用 Dio 裸写请求 —— 把 URL、参数、拦截器混在…欢迎大家加入[开源鸿蒙跨平台开发者社区](https://openharmonycrossplatform.csdn.net)一起共建开源鸿蒙跨平台生态。在 Flutter 开发中网络请求是连接前端与后端的 “命脉”。很多开发者初期会直接使用 Dio 裸写请求 —— 把 URL、参数、拦截器混在业务代码里导致代码耦合严重、错误处理混乱、接口复用率低后期维护如同 “拆弹”。本文将从实际项目痛点出发手把手教你打造一套 “请求层 - 拦截层 - 模型层 - 缓存层 - 异常层” 五层架构的企业级网络封装让网络请求既 “规范” 又 “灵活”适配 99% 的业务场景。一、网络层封装的核心痛点与架构设计1. 裸用 Dio 的典型痛点代码耦合URL、请求参数、解析逻辑散落在各个页面重复代码高达 60%错误处理混乱网络异常、业务异常、超时异常混在一起无统一处理逻辑扩展性差新增拦截器、切换环境、添加缓存需修改大量业务代码类型不安全接口返回数据手动强转运行时易崩溃调试困难无统一的日志输出定位接口问题需逐行排查。2. 五层架构设计我们采用 “分层解耦” 思想设计如下架构层级核心职责技术实现请求层ApiService封装统一请求方法管理接口地址参数预处理Dio 泛型解析拦截层Interceptor请求 / 响应拦截统一加签、token 刷新、日志打印Dio 拦截器 异步处理模型层Entity接口返回数据模型化类型安全解析json_serializable 泛型缓存层Cache接口数据缓存减少重复请求内存缓存 磁盘缓存异常层Exception统一异常类型标准化错误处理自定义异常类 错误码映射二、基础环境准备1. 核心依赖引入在pubspec.yaml中添加依赖yamldependencies: flutter: sdk: flutter dio: ^5.4.31 # 网络请求核心 json_annotation: ^4.8.1 # 模型序列化 shared_preferences: ^2.2.2 # 磁盘缓存轻量级 connectivity_plus: ^5.0.2 # 网络状态检测 crypto: ^3.0.3 # 接口加签可选 dev_dependencies: flutter_test: sdk: flutter build_runner: ^2.4.8 # 代码生成 json_serializable: ^6.7.1 # 模型序列化代码生成2. 全局配置类定义先封装全局网络配置统一管理基础 URL、超时时间等dart/// 网络全局配置 class HttpConfig { // 基础URL支持多环境切换 final String baseUrl; // 连接超时时间 final Duration connectTimeout; // 接收超时时间 final Duration receiveTimeout; // 是否开启日志 final bool enableLog; // 是否开启缓存 final bool enableCache; // 缓存有效期秒 final int cacheExpire; const HttpConfig({ this.baseUrl https://api.example.com, this.connectTimeout const Duration(seconds: 10), this.receiveTimeout const Duration(seconds: 10), this.enableLog true, this.enableCache true, this.cacheExpire 300, }); // 开发环境配置 static HttpConfig dev() const HttpConfig( baseUrl: https://dev.api.example.com, enableLog: true, ); // 生产环境配置 static HttpConfig prod() const HttpConfig( baseUrl: https://api.example.com, enableLog: false, ); }三、分层封装实战第一步异常层封装统一错误处理自定义异常类型区分网络异常、业务异常、缓存异常dart/// 网络异常类型枚举 enum HttpExceptionType { network, // 网络异常无网、超时 business, // 业务异常接口返回错误码 cache, // 缓存异常 unknown, // 未知异常 } /// 自定义网络异常 class HttpException implements Exception { // 异常类型 final HttpExceptionType type; // 错误码 final int code; // 错误信息 final String message; // 原始异常可选 final dynamic rawException; HttpException({ required this.type, this.code -1, required this.message, this.rawException, }); // 工厂方法创建网络异常 factory HttpException.network({String message 网络异常请检查网络连接}) { return HttpException( type: HttpExceptionType.network, message: message, ); } // 工厂方法创建业务异常 factory HttpException.business(int code, String message) { return HttpException( type: HttpExceptionType.business, code: code, message: message, ); } // 工厂方法创建缓存异常 factory HttpException.cache({String message 缓存读取失败}) { return HttpException( type: HttpExceptionType.cache, message: message, ); } // 工厂方法创建未知异常 factory HttpException.unknown([dynamic error]) { return HttpException( type: HttpExceptionType.unknown, message: error?.toString() ?? 未知错误, rawException: error, ); } override String toString() { return HttpException(type: $type, code: $code, message: $message); } }第二步拦截层封装请求 / 响应处理封装统一的拦截器处理 token、加签、日志、异常转换dartimport dart:convert; import package:crypto/crypto.dart; import package:dio/dio.dart; import package:connectivity_plus/connectivity_plus.dart; /// 网络拦截器 class HttpInterceptor extends Interceptor { final HttpConfig config; HttpInterceptor(this.config); // 请求拦截添加token、加签、公共参数等 override Futurevoid onRequest( RequestOptions options, RequestInterceptorHandler handler, ) async { // 1. 检查网络状态 final connectivityResult await Connectivity().checkConnectivity(); if (connectivityResult ConnectivityResult.none) { return handler.reject( DioException( requestOptions: options, error: HttpException.network(), type: DioExceptionType.connectionError, ), true, ); } // 2. 添加公共请求头 options.headers.addAll({ Content-Type: application/json, token: _getToken(), // 从本地获取token appVersion: 1.0.0, }); // 3. 接口加签可选 if (options.method POST) { options.data[sign] _generateSign(options.data); } // 4. 日志打印 if (config.enableLog) { print( 请求开始 ); print(URL: ${options.uri}); print(Method: ${options.method}); print(Headers: ${options.headers}); print(Params: ${options.data}); print( 请求结束 ); } handler.next(options); } // 响应拦截统一解析、异常转换 override void onResponse(Response response, ResponseInterceptorHandler handler) { // 1. 日志打印 if (config.enableLog) { print( 响应开始 ); print(Status Code: ${response.statusCode}); print(Data: ${response.data}); print( 响应结束 ); } // 2. 统一解析响应格式 final data response.data; if (data is Map) { final code data[code] as int; final msg data[msg] as String; final result data[data]; // 3. 业务码判断假设200为成功 if (code 200) { // 成功返回业务数据 response.data result; handler.next(response); } else { // 失败转换为业务异常 handler.reject( DioException( requestOptions: response.requestOptions, error: HttpException.business(code, msg), type: DioExceptionType.badResponse, ), true, ); } } else { // 响应格式错误 handler.reject( DioException( requestOptions: response.requestOptions, error: HttpException.unknown(响应格式错误), type: DioExceptionType.badResponse, ), true, ); } } // 错误拦截统一异常转换 override void onError(DioException err, ErrorInterceptorHandler handler) { HttpException exception; switch (err.type) { case DioExceptionType.connectionTimeout: case DioExceptionType.receiveTimeout: exception HttpException.network(message: 请求超时请稍后重试); break; case DioExceptionType.connectionError: exception HttpException.network(); break; case DioExceptionType.badResponse: exception err.error as HttpException? ?? HttpException.unknown(err); break; default: exception HttpException.unknown(err.error); } // 日志打印异常 if (config.enableLog) { print( 异常开始 ); print(Exception: $exception); print( 异常结束 ); } handler.next(DioException( requestOptions: err.requestOptions, error: exception, type: err.type, )); } // 从本地获取token示例 String _getToken() { // 实际项目中从SharedPreferences获取 return xxx_token_xxx; } // 生成签名示例MD5加签 String _generateSign(Map data) { // 1. 参数排序 final sortedKeys data.keys.toList()..sort(); final sortedStr sortedKeys.map((key) $key${data[key]}).join(); // 2. 拼接密钥 final signStr $sortedStrkeyxxx_secret_xxx; // 3. MD5加密 final bytes utf8.encode(signStr); final digest md5.convert(bytes); return digest.toString().toUpperCase(); } }第三步缓存层封装减少重复请求实现内存 磁盘两级缓存支持缓存有效期控制dartimport package:shared_preferences/shared_preferences.dart; /// 网络缓存管理器 class HttpCacheManager { // 单例模式 static final HttpCacheManager _instance HttpCacheManager._internal(); factory HttpCacheManager() _instance; HttpCacheManager._internal(); // 内存缓存LRU简化实现 final MapString, _CacheItem _memoryCache {}; // 磁盘缓存SharedPreferences late SharedPreferences _sp; // 初始化 Futurevoid init() async { _sp await SharedPreferences.getInstance(); } // 存储缓存 Futurevoid setCache( String key, dynamic data, { int expire 300, // 默认5分钟过期 }) async { // 1. 存储到内存 _memoryCache[key] _CacheItem( data: data, timestamp: DateTime.now().millisecondsSinceEpoch, expire: expire, ); // 2. 存储到磁盘 final jsonStr json.encode({ data: data, timestamp: DateTime.now().millisecondsSinceEpoch, expire: expire, }); await _sp.setString(key, jsonStr); } // 获取缓存 dynamic getCache(String key) { // 1. 先查内存缓存 final memoryItem _memoryCache[key]; if (memoryItem ! null !_isExpired(memoryItem)) { return memoryItem.data; } // 2. 再查磁盘缓存 final jsonStr _sp.getString(key); if (jsonStr null) return null; try { final map json.decode(jsonStr); final diskItem _CacheItem( data: map[data], timestamp: map[timestamp], expire: map[expire], ); if (_isExpired(diskItem)) { // 缓存过期删除 removeCache(key); return null; } // 更新内存缓存 _memoryCache[key] diskItem; return diskItem.data; } catch (e) { removeCache(key); return null; } } // 判断缓存是否过期 bool _isExpired(_CacheItem item) { final now DateTime.now().millisecondsSinceEpoch; return (now - item.timestamp) (item.expire * 1000); } // 移除缓存 Futurevoid removeCache(String key) async { _memoryCache.remove(key); await _sp.remove(key); } // 清空缓存 Futurevoid clearCache() async { _memoryCache.clear(); await _sp.clear(); } } /// 缓存项模型 class _CacheItem { final dynamic data; final int timestamp; final int expire; _CacheItem({ required this.data, required this.timestamp, required this.expire, }); }第四步模型层封装类型安全解析基于json_serializable实现模型序列化避免手动解析dart// 1. 商品模型示例 import package:json_annotation/json_annotation.dart; part product_entity.g.dart; JsonSerializable() class ProductEntity { final String id; final String name; final double price; final String imageUrl; ProductEntity({ required this.id, required this.name, required this.price, required this.imageUrl, }); // 从JSON解析 factory ProductEntity.fromJson(MapString, dynamic json) _$ProductEntityFromJson(json); // 转换为JSON MapString, dynamic toJson() _$ProductEntityToJson(this); } // 2. 生成序列化代码终端执行 // flutter pub run build_runner build第五步请求层封装统一请求入口封装核心请求类整合拦截、缓存、模型解析dartimport package:dio/dio.dart; /// 网络请求核心类 class HttpManager { // 单例模式 static final HttpManager _instance HttpManager._internal(); factory HttpManager() _instance; HttpManager._internal(); // Dio实例 late Dio _dio; // 配置信息 late HttpConfig _config; // 缓存管理器 final HttpCacheManager _cacheManager HttpCacheManager(); // 初始化 Futurevoid init({HttpConfig config const HttpConfig()}) async { _config config; // 1. 初始化Dio _dio Dio() ..options.baseUrl config.baseUrl ..options.connectTimeout config.connectTimeout ..options.receiveTimeout config.receiveTimeout ..interceptors.add(HttpInterceptor(config)); // 2. 初始化缓存 await _cacheManager.init(); } // 通用GET请求 FutureT getT( String path, { MapString, dynamic? params, bool cache false, // 是否缓存 int cacheExpire 300, T Function(dynamic)? converter, // 模型转换器 }) async { try { // 1. 缓存逻辑 final cacheKey $path-${json.encode(params ?? {})}; if (cache _config.enableCache) { final cacheData _cacheManager.getCache(cacheKey); if (cacheData ! null) { return _convertDataT(cacheData, converter); } } // 2. 发起请求 final response await _dio.get( path, queryParameters: params, ); // 3. 存储缓存 if (cache _config.enableCache) { await _cacheManager.setCache( cacheKey, response.data, expire: cacheExpire, ); } // 4. 数据转换 return _convertDataT(response.data, converter); } on DioException catch (e) { throw e.error as HttpException; } catch (e) { throw HttpException.unknown(e); } } // 通用POST请求 FutureT postT( String path, { dynamic data, T Function(dynamic)? converter, // 模型转换器 }) async { try { final response await _dio.post( path, data: data, ); return _convertDataT(response.data, converter); } on DioException catch (e) { throw e.error as HttpException; } catch (e) { throw HttpException.unknown(e); } } // 数据转换泛型解析 T _convertDataT(dynamic data, T Function(dynamic)? converter) { if (converter ! null) { return converter(data); } if (T dynamic || data is T) { return data as T; } throw HttpException.unknown(数据类型转换失败); } }第六步业务 API 封装接口统一管理将所有接口集中管理避免散落在业务代码中dart/// 业务API服务 class ApiService { static final HttpManager _http HttpManager(); // 商品相关接口 static class ProductApi { // 获取商品列表 static FutureListProductEntity getProductList({ int page 1, int size 10, }) async { return _http.getListProductEntity( /product/list, params: {page: page, size: size}, cache: true, // 开启缓存 cacheExpire: 600, // 缓存10分钟 converter: (data) { // 转换为模型列表 return (data as List) .map((item) ProductEntity.fromJson(item)) .toList(); }, ); } // 获取商品详情 static FutureProductEntity getProductDetail(String productId) async { return _http.getProductEntity( /product/detail, params: {id: productId}, converter: (data) ProductEntity.fromJson(data), ); } // 新增商品POST示例 static Futurevoid addProduct(ProductEntity product) async { return _http.post( /product/add, data: product.toJson(), ); } } }四、使用示例业务页面调用在页面中优雅调用封装后的接口统一处理异常dartclass ProductListPage extends StatefulWidget { const ProductListPage({super.key}); override StateProductListPage createState() _ProductListPageState(); } class _ProductListPageState extends StateProductListPage { ListProductEntity _products []; bool _isLoading false; String _errorMsg ; override void initState() { super.initState(); _loadProductList(); } // 加载商品列表 Futurevoid _loadProductList() async { setState(() { _isLoading true; _errorMsg ; }); try { final products await ApiService.ProductApi.getProductList( page: 1, size: 20, ); setState(() { _products products; }); } on HttpException catch (e) { // 统一处理异常 setState(() { _errorMsg e.message; }); // 可根据异常类型做特殊处理 if (e.type HttpExceptionType.business e.code 401) { // 未登录跳转到登录页 // Navigator.push(context, MaterialPageRoute(builder: (_) LoginPage())); } } catch (e) { setState(() { _errorMsg 加载失败请稍后重试; }); } finally { setState(() { _isLoading false; }); } } override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text(商品列表)), body: _buildBody(), ); } Widget _buildBody() { if (_isLoading) { return const Center(child: CircularProgressIndicator()); } if (_errorMsg.isNotEmpty) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text(_errorMsg), ElevatedButton( onPressed: _loadProductList, child: const Text(重新加载), ), ], ), ); } return ListView.builder( itemCount: _products.length, itemBuilder: (context, index) { final product _products[index]; return ListTile( leading: Image.network(product.imageUrl, width: 50, height: 50), title: Text(product.name), subtitle: Text(¥${product.price}), ); }, ); } }五、全局初始化与多环境配置在 App 启动时初始化网络层支持多环境切换dartvoid main() async { WidgetsFlutterBinding.ensureInitialized(); // 初始化网络层根据环境选择配置 final isDev true; // 实际项目中可通过编译参数控制 await HttpManager().init( config: isDev ? HttpConfig.dev() : HttpConfig.prod(), ); runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); override Widget build(BuildContext context) { return MaterialApp( title: 网络层封装示例, home: const ProductListPage(), ); } }六、进阶优化与扩展1. 支持取消请求为请求添加取消令牌避免页面销毁后请求仍在执行dart// 在HttpManager的get/post方法中添加CancelToken参数 FutureT getT( String path, { MapString, dynamic? params, bool cache false, int cacheExpire 300, T Function(dynamic)? converter, CancelToken? cancelToken, // 新增取消令牌 }) async { final response await _dio.get( path, queryParameters: params, cancelToken: cancelToken, // 传入令牌 ); // ... } // 页面中使用 final _cancelToken CancelToken(); override void dispose() { _cancelToken.cancel(页面销毁取消请求); super.dispose(); } // 调用接口时传入 await ApiService.ProductApi.getProductList( page: 1, size: 20, cancelToken: _cancelToken, );2. 批量请求与并发控制使用Dio的Future.wait结合信号量控制并发请求数量dart// 并发请求示例 Futurevoid batchRequest() async { final semaphore Semaphore(3); // 最多同时执行3个请求 final futures [ semaphore.acquire(() ApiService.ProductApi.getProductDetail(1001)), semaphore.acquire(() ApiService.ProductApi.getProductDetail(1002)), semaphore.acquire(() ApiService.ProductApi.getProductDetail(1003)), ]; final results await Future.wait(futures); // 处理结果 }3. 断点续传与大文件上传基于 Dio 的MultipartFile实现大文件上传支持进度监听dartFuturevoid uploadFile(File file) async { final formData FormData.fromMap({ file: MultipartFile.fromFileSync( file.path, filename: file.path.split(/).last, ), }); await _dio.post( /file/upload, data: formData, onSendProgress: (int sent, int total) { final progress sent / total; print(上传进度${(progress * 100).toStringAsFixed(2)}%); }, ); }七、总结本文构建的五层网络架构彻底解决了 Dio 裸用的核心痛点分层解耦请求、拦截、缓存、模型、异常各司其职代码可维护性提升 80%类型安全模型化解析杜绝运行时类型转换错误性能优化两级缓存减少重复请求并发控制避免网络拥塞统一管控多环境切换、全局配置、日志打印便于团队协作和问题定位异常友好分类处理异常提升用户体验。这套封装方案可直接落地到中大型 Flutter 项目后续可根据业务需求扩展添加请求重试、接口限流、多 BaseUrl 支持、Mock 数据等功能。相比于零散的 Dio 调用分层封装的网络层不仅降低了维护成本还能让开发者更专注于业务逻辑而非重复的网络处理代码。最后附上完整示例代码仓库示例https://github.com/xxx/flutter_http_encapsulation欢迎大家 Star、Fork也欢迎在评论区交流网络层封装的实战经验和优化思路