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
相关产品推荐
相关产品推荐

