Flutter解析JSON报错_InternalLinkedHashMap非int子类型如何修复
Flutter 接口对接报错
type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'int' 修复方案 错误根因
报错来自JSON反序列化阶段的类型不匹配:模型中声明为int类型的字段,实际接收到的接口返回值是嵌套的Map结构(Dart解析JSON时默认转成_InternalLinkedHashMap类型),直接赋值触发强转失败。
从给出的代码判断,问题集中在MachineRequestModel.fromJson里直接赋值的几个关联字段:machine、customer、machine_owner。这几个字段如果在模型里定义为int类型(通常用来存关联数据的ID),但接口实际返回了完整的关联对象JSON结构,直接赋值就会触发这个报错。如果这几个字段本身定义的是对象类型,没有做嵌套反序列化,后续使用时也会触发同类错误。
修复步骤
1. 先对齐字段和接口返回结构
先打印单条请求数据的原始JSON,确认几个关联字段的实际返回格式:
- 如果
machine/customer/machine_owner应该存int类型的关联ID,但是接口返回了完整对象,就从对象里取id字段赋值 - 如果这几个字段需要存完整的关联信息,就给每个关联实体单独写模型,做嵌套反序列化
2. 重写fromJson方法,补全显式类型转换
不要依赖Dart的动态类型隐式转换,所有字段都做显式的类型判断和兼容处理,适配接口可能返回的不同值格式:
场景1:关联字段只需要存储int类型的ID
如果模型里machine、customer、machine_owner字段是int类型,修改fromJson如下:
MachineRequestModel.fromJson(Map<String, dynamic> json) { // 基础字段做类型兼容,支持接口传int/字符串格式的数字 id = json['id'] is int ? json['id'] : int.tryParse(json['id'].toString()) ?? 0; location = json['location']?.toString(); // 布尔值兼容接口返回true/false、1/0两种格式 is_accepted = json['is_accepted'] == true || json['is_accepted'] == 1; is_complete = json['is_complete'] == true || json['is_complete'] == 1; // 关联字段如果返回Map就取内部id,返回int就直接赋值 machine = json['machine'] is int ? json['machine'] : int.tryParse(json['machine']?['id']?.toString() ?? '0') ?? 0; customer = json['customer'] is int ? json['customer'] : int.tryParse(json['customer']?['id']?.toString() ?? '0') ?? 0; machine_owner = json['machine_owner'] is int ? json['machine_owner'] : int.tryParse(json['machine_owner']?['id']?.toString() ?? '0') ?? 0; from_date = DateTime.tryParse(json['from_date']?.toString() ?? ''); to_date = DateTime.tryParse(json['to_date']?.toString() ?? ''); // 金额字段兼容int、String、double三种格式,避免parse直接崩溃 total_price = double.tryParse(json['total_price']?.toString() ?? '0') ?? 0; }
场景2:关联字段需要存储完整对象
先分别创建Machine、Customer、User(对应machine_owner)的实体类,实现各自的fromJson方法,再做嵌套反序列化:
MachineRequestModel.fromJson(Map<String, dynamic> json) { id = json['id'] is int ? json['id'] : int.tryParse(json['id'].toString()) ?? 0; location = json['location']?.toString(); is_accepted = json['is_accepted'] == true || json['is_accepted'] == 1; is_complete = json['is_complete'] == true || json['is_complete'] == 1; // 嵌套解析关联对象 machine = json['machine'] != null ? Machine.fromJson(json['machine']) : null; customer = json['customer'] != null ? Customer.fromJson(json['customer']) : null; machine_owner = json['machine_owner'] != null ? User.fromJson(json['machine_owner']) : null; from_date = DateTime.tryParse(json['from_date']?.toString() ?? ''); to_date = DateTime.tryParse(json['to_date']?.toString() ?? ''); total_price = double.tryParse(json['total_price']?.toString() ?? '0') ?? 0; }
3. 补全Provider层的类型校验
在解析数组前先做类型判断,避免接口结构变动触发其他类型错误:
if (apiResponse.response != null && apiResponse.response.statusCode == 200) { final Map<String, dynamic> _map = apiResponse.response.data; // 先校验requests字段是否为数组类型 if (_map['requests'] is List) { machineRequests = (_map['requests'] as List) .map<MachineRequestModel>((value) => MachineRequestModel.fromJson(value as Map<String, dynamic>)) .toList(); } notifyListeners(); return machineRequests; }
避坑提示
- 所有JSON解析不要直接用
parse方法,优先用tryParse加默认值,避免接口传非预期值时直接崩溃 - 布尔、数字类型的字段要做格式兼容,后端很可能返回0/1代替布尔值、返回字符串格式的数字代替数值类型
- 不要依赖动态类型的隐式转换,所有字段赋值前明确判断类型,从根源上避免运行时类型错误
内容的提问来源于stack exchange,提问作者Brooke Stanley
相关产品推荐
相关产品推荐

