Flutter中解析API响应保存至SQLite时出现HashMap转Integer异常的模型实现求助
解决Flutter中API响应解析后SQLite插入类型不匹配问题
错误根源分析
你遇到的java.util.HashMap cannot be cast to java.lang.Integer错误,核心原因是插入逻辑不匹配:你的数据库表是为单条博物馆记录(对应Data类)设计的,但你直接把包含整个data数组的MuseumsList对象传给了insert方法。MuseumsList的toJson返回的是{"data": [数组]}结构,而SQLite的insert期望的是与表字段一一对应的键值对Map,这种结构差异导致了类型转换失败。
分步解决方案
1. 调整数据库操作方法(支持批量/单条插入)
修改DBProvider,新增批量插入方法(效率更高),同时保留单条插入的能力:
// 单条插入方法(针对单个Data对象) Future<Data> create(Data museum) async { final db = await instance.database; final insertedId = await db!.insert(tableMuseums, museum.toJson()); print("博物馆记录ID $insertedId 已保存"); // 如果需要返回带插入ID的对象,可以给Data类加copy方法,否则直接返回原对象 return museum; } // 批量插入方法(处理整个Data列表) Future<void> createBatch(List<Data> museums) async { final db = await instance.database; final batch = db!.batch(); for (var museum in museums) { batch.insert(tableMuseums, museum.toJson()); } await batch.commit(noResult: true); print("所有博物馆记录已批量保存到数据库"); }
2. 修复服务层的插入逻辑
在MuseumsService中,不再直接插入MuseumsList,而是遍历它的data列表进行批量插入:
if (response.statusCode == 200) { print('$loginAPIURL 接口响应:'); print(response.body); MuseumsList museums = MuseumsList.fromJson(jsonDecode(response.body)); // 调用批量插入方法 await DBProvider.instance.createBatch(museums.data!); }
3. 完善模型的空值处理(避免潜在崩溃)
你的API响应中部分字段是"null"字符串,直接用DateTime.parse会报错,需要在Data.fromJson中添加空值判断:
Data.fromJson(Map<String, dynamic> json) { id = json['id']; name = json['name']; sessionTime = json['session_time']; distId = json['distId']; photo = json['photo']; address = json['address']; lat = json['lat']; long = json['long']; sectionId = json['sectionId']; email = json['email']; // 处理日期字段的"null"字符串 updatedAt = json["updated_at"] != "null" ? DateTime.parse(json["updated_at"]) : null; createdAt = json["created_at"] != "null" ? DateTime.parse(json["created_at"]) : null; }
同时在Data.toJson中对可能为null的日期字段做安全处理:
Map<String, Object?> toJson() => { MuseumsFields.MUSEUM_ID: id, MuseumsFields.MUSEUM_NAME: name, MuseumsFields.SESSION_TIME: sessionTime, MuseumsFields.MUSEUM_DIST_ID: distId, MuseumsFields.MUSEUM_PHOTO: photo, MuseumsFields.MUSEUM_ADDRESS: address, MuseumsFields.LAT: lat, MuseumsFields.LONG: long, MuseumsFields.MUSEUM_SECTION_ID: sectionId, MuseumsFields.EMAIL: email, MuseumsFields.UPDATED_AT: updatedAt?.toIso8601String(), MuseumsFields.CREATED_AT: createdAt?.toIso8601String(), };
关键说明
- 批量插入使用SQLite的
batch操作,比循环调用单条插入效率高很多,适合处理多条数据的场景。 - 空值处理是为了避免API返回异常字符串时导致的解析崩溃,让代码更健壮。
- 你的
Data类的toJson方法本身是正确的,问题出在调用方式上——应该传入单个Data对象,而不是整个MuseumsList。
内容的提问来源于stack exchange,提问作者RexLudus
相关产品推荐
相关产品推荐

