You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 21:30:54