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

Flutter中PODO模型解析API JSON无输出问题求助

问题

我为业务模型创建了包含Data、Child、Materials三层结构的PODO类,实现了fromJson和toJson序列化方法:

class Data {

  String? parentWo;
  String? parentWoDesc;
  String? parentWoStatus;
  String? parentWoStatusDate;
  String? parentWoWorkType;
  String? parentWoClass;
  String? parentWoCrew;
  String? parentWoLead;
  String? parentWoLocation;
  String? parentWoDepartmentDescription;
  String? parentWoSectionDescription;
  List<Child>? children;

  Data({
    this.parentWo,
    this.parentWoDesc,
    this.parentWoStatus,
    this.parentWoStatusDate,
    this.parentWoWorkType,
    this.parentWoClass,
    this.parentWoCrew,
    this.parentWoLead,
    this.parentWoLocation,
    this.parentWoDepartmentDescription,
    this.parentWoSectionDescription,
    this.children,
  });

  factory Data.fromJson(Map<String, dynamic> json) {
    var list = json['children'] as List;
    print(list.runtimeType);
    List<Child> childrenlist = list.map((i) => Child.fromJson(i)).toList();

    return Data(
      parentWo: json["parentWo"] ?? 'VADER',
      parentWoDesc: json["parentWoDesc"],
      parentWoStatus: json["parentWoStatus"],
      parentWoStatusDate: json["parentWoStatusDate"],
      parentWoWorkType: json["parentWoWorkType"],
      parentWoClass: json["parentWoClass"],
      parentWoCrew: json["parentWoCrew"],
      parentWoLead: json["parentWoLead"],
      parentWoLocation: json["parentWoLocation"],
      parentWoDepartmentDescription: json["parentWoDepartmentDescription"],
      parentWoSectionDescription: json["parentWoSectionDescription"],
      children:
          childrenlist,
    );
  }
  

  Map<String, dynamic> toJson() => {
        "parentWo": parentWo,
        "parentWoDesc": parentWoDesc,
        "parentWoStatus": parentWoStatus,
        "parentWoStatusDate": parentWoStatusDate,
        "parentWoWorkType": parentWoWorkType,
        "parentWoClass": parentWoClass,
        "parentWoCrew": parentWoCrew,
        "parentWoLead": parentWoLead,
        "parentWoLocation": parentWoLocation,
        "parentWoDepartmentDescription": parentWoDepartmentDescription,
        "parentWoSectionDescription": parentWoSectionDescription,
        "children": List<dynamic>.from(children!.map((x) => x.toJson())),
      };
}

class Child {

  String? woNum;
  String? woDesc;
  String? woStatus;
  DateTime? woStatusDate;
  String? woCrew;
  String? woLead;
  String? woLocation;
  List<Materials>? materials;

  Child({
    this.woNum,
    this.woDesc,
    this.woStatus,
    this.woStatusDate,
    this.woCrew,
    this.woLead,
    this.woLocation,
    this.materials,
  });

  factory Child.fromJson(Map<String, dynamic> json) {
    var list = json['materials'] as List;
    print(list.runtimeType);
    List<Materials> materialslist = list.map((i) => Materials.fromJson(i)).toList();

    return Child(
        woNum: json["woNum"],
        woDesc: json["woDesc"],
        woStatus: json["woStatus"],
        woStatusDate: DateTime.parse(json["woStatusDate"]),
        woCrew: json["woCrew"],
        woLead: json["woLead"],
        woLocation: json["woLocation"],
        materials: materialslist,
      );
  } 

  Map<String, dynamic> toJson() => {
        "woNum": woNum,
        "woDesc": woDesc,
        "woStatus": woStatus,
        "woStatusDate": woStatusDate!.toIso8601String(),
        "woCrew": woCrew,
        "woLead": woLead,
        "woLocation": woLocation,
        "materials": List<dynamic>.from(materials!.map((x) => x.toJson())),
      };
  get length => null;
}

class Materials {

  String? itemNum;
  String? itemDescription;
  int? itemQuantityPlan;
  int? itemQuantityIssued;
  int? itemWoBalance;
  int? itemInventoryBalance;
  String? itemCommodity;
  String? itemIssueUnit;
  bool? itemStructure;
  bool? itemDtPole;
  
  Materials({
    this.itemNum,
    this.itemDescription,
    this.itemQuantityPlan,
    this.itemQuantityIssued,
    this.itemWoBalance,
    this.itemInventoryBalance,
    this.itemCommodity,
    this.itemIssueUnit,
    this.itemStructure,
    this.itemDtPole,
  });

  factory Materials.fromJson(Map<String, dynamic> json) => Materials(
        itemNum: json["itemNum"],
        itemDescription: json["itemDescription"],
        itemQuantityPlan: json["itemQuantityPlan"],
        itemQuantityIssued: json["itemQuantityIssued"],
        itemWoBalance: json["itemWoBalance"],
        itemInventoryBalance: json["itemInventoryBalance"],
        itemCommodity: json["itemCommodity"],
        itemIssueUnit: json["itemIssueUnit"],
        itemStructure: json["itemStructure"],
        itemDtPole: json["itemDtPole"],
      );

  Map<String, dynamic> toJson() => {
        "itemNum": itemNum,
        "itemDescription": itemDescription,
        "itemQuantityPlan": itemQuantityPlan,
        "itemQuantityIssued": itemQuantityIssued,
        "itemWoBalance": itemWoBalance,
        "itemInventoryBalance": itemInventoryBalance,
        "itemCommodity": itemCommodity,
        "itemIssueUnit": itemIssueUnit,
        "itemStructure": itemStructure,
        "itemDtPole": itemDtPole,
      };
  @override
  String toString() {
    // TODO: implement toString
    return '$itemNum';
  }
}

现在解析API返回的JSON响应时遇到问题,以下是API请求与解析代码:

Future loadParent2() async {

    Map data = {'wonum': WOInputted};

    var bodyy = json.encode(data);

    var jsonString = await http.post(
        Uri.parse("https://sample.com.ph/extension/list/"),
        headers: {
          'Content-type': 'application/json',
          'Authorization': 'Bearer $getAccessToken'
        },
        body: bodyy);
      
    final jsonResponse = jsonDecode(jsonString.body);
    final valueResponse = jsonResponse['results']['status_code'];
    
    if (jsonString.statusCode == 200 && valueResponse == '1') {
      print('NO RESULTS IN PARENT WO');
      print('VALUE RESPONSE: $valueResponse');
      
     
    } else if (jsonString.statusCode == 200 && valueResponse == '0') {
      print('THIS HAVE RESULTS IN PARENT WO');
      print('VALUE RESPONSE: $valueResponse');
      sampleParentWO = jsonResponse['results']['data']['parentWo'];
      final parentWOResponse = jsonResponse['results']['data'];
      print(parentWOResponse); //能正常打印,说明拿到了正确响应
      
      Data dataPick = new Data.fromJson(parentWOResponse); //不确定是否成功保存到PODO
      print(dataPick.parentWo); //无输出
      mainParentPick = Data.fromJson(parentWOResponse);
      print(mainParentPick.parentWo); //依旧无输出
      print(mainParentPick); //无输出
      return mainParentPick;
    }
    
    else {
      throw Exception('Failed there\'s an error');
    }
  }

能正常打印parentWOResponse,但实例化Data对象后,打印dataPick.parentWo、mainParentPick.parentWo及mainParentPick均无输出,请问问题出在哪?需要怎么修复?

解决方案

1. 捕获fromJson中的嵌套解析异常

当前代码强制将json['children']和json['materials']转为List,一旦API返回的这两个字段不存在、为null或不是List类型,会直接抛出异常导致代码中断,后续的print语句根本不会执行。同时日期解析也没有异常处理,格式错误会直接崩溃。

修改Data.fromJson:

factory Data.fromJson(Map<String, dynamic> json) {
  List<Child> childrenlist = [];
  // 先判断children字段是否存在且为List类型
  if (json['children'] != null && json['children'] is List) {
    var list = json['children'] as List;
    childrenlist = list.map((i) => Child.fromJson(i)).toList();
  }

  return Data(
    parentWo: json["parentWo"] ?? 'VADER',
    parentWoDesc: json["parentWoDesc"],
    parentWoStatus: json["parentWoStatus"],
    parentWoStatusDate: json["parentWoStatusDate"],
    parentWoWorkType: json["parentWoWorkType"],
    parentWoClass: json["parentWoClass"],
    parentWoCrew: json["parentWoCrew"],
    parentWoLead: json["parentWoLead"],
    parentWoLocation: json["parentWoLocation"],
    parentWoDepartmentDescription: json["parentWoDepartmentDescription"],
    parentWoSectionDescription: json["parentWoSectionDescription"],
    children: childrenlist,
  );
}

修改Child.fromJson:

factory Child.fromJson(Map<String, dynamic> json) {
  List<Materials> materialslist = [];
  if (json['materials'] != null && json['materials'] is List) {
    var list = json['materials'] as List;
    materialslist = list.map((i) => Materials.fromJson(i)).toList();
  }

  DateTime? statusDate;
  // 处理日期解析异常
  if (json["woStatusDate"] != null) {
    try {
      statusDate = DateTime.parse(json["woStatusDate"]);
    } catch (e) {
      print('日期解析失败: $e');
    }
  }

  return Child(
      woNum: json["woNum"],
      woDesc: json["woDesc"],
      woStatus: json["woStatus"],
      woStatusDate: statusDate,
      woCrew: json["woCrew"],
      woLead: json["woLead"],
      woLocation: json["woLocation"],
      materials: materialslist,
    );
}

2. 给Data类添加toString方法

当前Data类没有重写toString,直接打印实例会输出默认的内存地址,看起来像无输出。添加自定义toString方便调试:

class Data {
  // ... 原有字段和构造方法 ...

  @override
  String toString() {
    return 'Data{parentWo: $parentWo, parentWoDesc: $parentWoDesc, childrenCount: ${children?.length ?? 0}}';
  }
}

3. 验证API返回字段的键名匹配

确认parentWOResponse中的parentWo键名是否和PODO类中的一致(比如API返回的是parentwo小写,而你用的是parentWo驼峰)。可以在打印parentWOResponse后添加一行:

print('parentWo字段值: ${parentWOResponse['parentWo']}');

如果输出为空,说明键名不匹配或者该字段本身就是null。

4. 给loadParent2添加全局异常捕获

在方法外层包裹try-catch,捕获所有异常并打印堆栈信息,快速定位问题:

Future loadParent2() async {
  try {
    // 原有代码...
  } catch (e, stackTrace) {
    print('解析过程出错: $e');
    print('错误堆栈: $stackTrace');
    rethrow;
  }
}

内容的提问来源于stack exchange,提问作者Kim Lo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 09:18:24