Flutter中处理键全唯一的JSON数据:序列化异常解决
解决方案
你的问题根源在于JSON结构和模型类不匹配:原JSON的顶层就是一组以transaction_xxx为键的交易对象集合,而你的HystoryOperations类错误地试图读取一个名为transaction的键(但这个键在JSON中根本不存在),导致类型转换异常。
以下是正确的实现步骤:
1. 定义单个交易的模型类
先为每个交易对象创建强类型模型,确保序列化/反序列化的类型安全:
import 'package:json_annotation/json_annotation.dart'; part 'transaction.g.dart'; @JsonSerializable() class Transaction { final String date; final String time; final double sum; final int id_order; final String status_order; final String type_order; Transaction({ required this.date, required this.time, required this.sum, required this.id_order, required this.status_order, required this.type_order, }); factory Transaction.fromJson(Map<String, dynamic> json) => _$TransactionFromJson(json); Map<String, dynamic> toJson() => _$TransactionToJson(this); }
2. 修改历史操作模型类
调整HystoryOperations,直接接收顶层的交易集合Map,而不是寻找不存在的transaction键:
import 'package:json_annotation/json_annotation.dart'; import 'transaction.dart'; part 'hystory_operations.g.dart'; @JsonSerializable() class HystoryOperations { final Map<String, Transaction> transactions; HystoryOperations({required this.transactions}); factory HystoryOperations.fromJson(Map<String, dynamic> json) => _$HystoryOperationsFromJson(json); Map<String, dynamic> toJson() => _$HystoryOperationsToJson(this); }
3. 生成序列化代码
运行json_serializable的代码生成命令:
flutter pub run build_runner build
生成的代码会自动将顶层JSON的键值对转换为Map<String, Transaction>,无需手动处理类型转换。
4. 使用示例
在你的Dio请求方法中,返回的HystoryOperations可以直接遍历交易集合:
Future<HystoryOperations> getDataDio() async { try { final Dio dio = Dio(); final response = await dio.get('https://run.mocky.io/v3/26681b8c-6581-4b8b-8fbe-3da2dc7bb785'); return HystoryOperations.fromJson(response.data); } on DioError catch (e) { print('error log: ${e.error}'); rethrow; // 建议抛出异常让上层处理 } } // 使用示例 void printTransactions() async { final operations = await getDataDio(); operations.transactions.forEach((transactionKey, transaction) { print('交易标识: $transactionKey'); print('订单ID: ${transaction.id_order}'); print('交易金额: ${transaction.sum}'); print('交易状态: ${transaction.status_order}\n'); }); }
可选:简化实现(无单独模型类)
如果不需要强类型校验,也可以直接将顶层JSON转为Map<String, dynamic>,但不推荐(类型不安全):
Future<Map<String, dynamic>> getDataDio() async { try { final Dio dio = Dio(); final response = await dio.get('https://run.mocky.io/v3/26681b8c-6581-4b8b-8fbe-3da2dc7bb785'); return response.data as Map<String, dynamic>; } on DioError catch (e) { print('error log: ${e.error}'); rethrow; } }
内容的提问来源于stack exchange,提问作者bahmN
相关产品推荐
相关产品推荐

