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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 18:55:02