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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 11:12:21