Flutter请求API报_InternalLinkedHashMap无法转List错误及模型适配方案
报错根因
出现的类型不匹配问题完全来自模型定义与API实际返回结构的错位,具体错位点:
- 原模型将
json_response字段定义为单个实体对象,但实际API返回的json_response是对象数组(List结构) - 原模型定义
CheckpointsModel的fromJson方法仅接收数组入参,但API返回的checkpoint字段是单个Map结构,传入参数时直接触发_InternalLinkedHashMap<String, dynamic>无法转换为List<dynamic>的类型错误 - 代码中引用了未定义的
ComprovantesInfoModel类,存在拼写/定义缺失问题 - 未定义
checkpoint下resources数组对应的实体,无法直接访问嵌套资源内容
修复后的可直接运行Model代码
将原Model.dart的内容全部替换为以下定义即可:
// 顶层响应模型 class ComprovanteModel { List<ComprovanteInfoModel> jsonResponse; String error; ComprovanteModel({this.jsonResponse, this.error}); factory ComprovanteModel.fromJson(Map<String, dynamic> json) { return ComprovanteModel( // 将json_response对应的数组映射为实体列表 jsonResponse: (json['json_response'] as List<dynamic>) .map((item) => ComprovanteInfoModel.fromJson(item)) .toList(), error: '', ); } ComprovanteModel.withError(String errorValue) : jsonResponse = null, error = errorValue; } // 单条Comprovante对应的实体 class ComprovanteInfoModel { String clientFormalName; int volumes; int duration; CheckpointModel checkpoint; // 可按需补充其他API返回字段映射,比如deadline、depot_id、service_id等 ComprovanteInfoModel({ this.clientFormalName, this.duration, this.volumes, this.checkpoint, }); factory ComprovanteInfoModel.fromJson(Map<String, dynamic> json) { return ComprovanteInfoModel( clientFormalName: json['client_formal_name'], volumes: json['volumes'], duration: json['duration'], // checkpoint为单Map对象,直接传入单对象解析方法 checkpoint: CheckpointModel.fromJson(json['checkpoint']), ); } } // 单条Checkpoint对应的实体 class CheckpointModel { int checkpointId; String arrivalTime; int status; int eventId; List<ResourceModel> resources; // 可按需补充其他checkpoint下的字段,比如operation_date、obs等 CheckpointModel({ this.checkpointId, this.arrivalTime, this.status, this.eventId, this.resources, }); factory CheckpointModel.fromJson(Map<String, dynamic> json) { return CheckpointModel( checkpointId: json['checkpoint_id'], arrivalTime: json['arrival_time'], status: json['status'], eventId: json['event_id'], // 解析resources数组 resources: (json['resources'] as List<dynamic>) .map((resItem) => ResourceModel.fromJson(resItem)) .toList(), ); } } // resources数组对应的实体 class ResourceModel { String contentType; int serviceEventEffectId; String content; String contentLabel; String userEffectUniqueCode; ResourceModel({ this.contentType, this.serviceEventEffectId, this.content, this.contentLabel, this.userEffectUniqueCode, }); factory ResourceModel.fromJson(Map<String, dynamic> json) { return ResourceModel( contentType: json['content_type'], serviceEventEffectId: json['service_event_effect_id'], content: json['content'], contentLabel: json['content_label'], userEffectUniqueCode: json['user_effect_unique_code'], ); } }
解析逻辑验证
替换完模型后,调用API拿到原始响应后直接走标准解析流程即可:
// 假设response为http请求返回的响应对象 final rawResponse = jsonDecode(response.body); final comprovanteData = ComprovanteModel.fromJson(rawResponse); // 直接访问嵌套的resources内容 for (final item in comprovanteData.jsonResponse) { final currentCheckpoint = item.checkpoint; for (final resource in currentCheckpoint.resources) { // 可直接获取resources内的所有字段值 debugPrint(resource.contentType); debugPrint(resource.content); } }
关键说明
- JSON结构与Dart实体的对应规则:JSON中用
{}包裹的对象结构,对应Dart的Map<String, dynamic>类型,需映射为自定义实体类;JSON中用[]包裹的数组结构,对应Dart的List<dynamic>类型,需通过map遍历转换为实体类列表。 - 所有
fromJson方法建议使用factory构造函数实现,避免初始化列表隐式触发的类型转换报错。 - 对API返回中可能为null的字段,可在解析时加判空兜底,比如
checkpointId: json['checkpoint_id'] ?? 0,避免空值导致的类型错误。 - 原代码中多余的
CheckpointsModel类可直接删除,当前API结构中不存在嵌套的checkpoint数组。
内容的提问来源于stack exchange,提问作者Iury
相关产品推荐
相关产品推荐

