Flutter/Dart中重复嵌套对象引发JSON解码失败
解决方案
1. 适配schedule字段的两种返回格式
问题核心是后端返回的schedule存在两种格式:完整对象Map,或是仅代表id的int值。直接修改Schedule.fromJSON方法,先判断输入类型再处理:
factory Schedule.fromJSON(dynamic json) { // 处理仅返回id的情况 if (json is int) { return Schedule( id: json, serviceId: 0, // 可根据业务需求设为null或默认值 locationDescription: '', dateTimeStart: '', dateTimeEnd: '', recurrence: '', ); } // 处理正常的对象格式 return Schedule( id: json['id'], serviceId: json['serviceId'], locationDescription: json['locationDescription'], dateTimeStart: json['dateTimeStart'], dateTimeEnd: json['dateTimeEnd'], recurrence: json['recurrence'], ); }
2. 加入缓存复用已解析的Schedule实例
如果希望相同id的Schedule复用同一个实例(避免重复创建,同时保留完整数据),可以添加缓存机制:
先定义一个缓存Map:
final Map<int, Schedule> _scheduleCache = {};
再修改Schedule.fromJSON:
factory Schedule.fromJSON(dynamic json) { late int scheduleId; Schedule? existingSchedule; if (json is int) { scheduleId = json; // 缓存中有就直接返回,没有则构造基础实例并存入缓存 existingSchedule = _scheduleCache[scheduleId]; if (existingSchedule != null) return existingSchedule; final schedule = Schedule( id: scheduleId, serviceId: 0, locationDescription: '', dateTimeStart: '', dateTimeEnd: '', recurrence: '', ); _scheduleCache[scheduleId] = schedule; return schedule; } else { scheduleId = json['id']; existingSchedule = _scheduleCache[scheduleId]; if (existingSchedule != null) return existingSchedule; final schedule = Schedule( id: json['id'], serviceId: json['serviceId'], locationDescription: json['locationDescription'], dateTimeStart: json['dateTimeStart'], dateTimeEnd: json['dateTimeEnd'], recurrence: json['recurrence'], ); _scheduleCache[scheduleId] = schedule; return schedule; } }
这样第二个Appointment的schedule字段为int时,会直接复用第一个已解析的完整Schedule实例,不会出现数据缺失。
3. 增加异常捕获提升稳定性
为避免其他意外格式导致崩溃,可以在解析逻辑中加入异常捕获:
factory Schedule.fromJSON(dynamic json) { try { if (json is int) { return Schedule( id: json, serviceId: 0, locationDescription: '', dateTimeStart: '', dateTimeEnd: '', recurrence: '', ); } else if (json is Map<String, dynamic>) { return Schedule( id: json['id'], serviceId: json['serviceId'], locationDescription: json['locationDescription'], dateTimeStart: json['dateTimeStart'], dateTimeEnd: json['dateTimeEnd'], recurrence: json['recurrence'], ); } else { // 非法格式返回默认实例 return Schedule( id: -1, serviceId: 0, locationDescription: '', dateTimeStart: '', dateTimeEnd: '', recurrence: '', ); } } catch (e) { print('Schedule解析错误: $e'); return Schedule( id: -1, serviceId: 0, locationDescription: '', dateTimeStart: '', dateTimeEnd: '', recurrence: '', ); } }
为什么修改==和hashCode无效?
你之前修改Schedule的相等性判断方法,是为了处理实例的比较逻辑,但问题根源是后端返回的JSON结构本身发生了变化(从完整对象变为int值),和实例的相等性无关,因此无法解决解析错误。
内容的提问来源于stack exchange,提问作者Dana
相关产品推荐
相关产品推荐

