Flutter解析JSON响应时抛出错误,求问题排查与定位方法
JSON解析失败问题排查与修复
问题背景
尝试解析以下JSON响应:
{"GetOptionsResult":[{"OptionGroup":null,"OptionGroupID":0,"OptionDisplayName":"290/200 HP V8 Engine","OptionCode":"1008852"},{"OptionGroup":null,"OptionGroupID":0,"OptionDisplayName":"290/225 HP V8 Engine","OptionCode":"1007059"},{"OptionGroup":null,"OptionGroupID":0,"OptionDisplayName":"343/235 HP V8 Engine","OptionCode":"1008853"},{"OptionGroup":null,"OptionGroupID":0,"OptionDisplayName":"343/280 HP V8 Engine","OptionCode":"1005857"},{"OptionGroup":null,"OptionGroupID":0,"OptionDisplayName":"360/315 HP V8 Engine","OptionCode":"1008854"},{"OptionGroup":null,"OptionGroupID":0,"OptionDisplayName":"390/315 HP V8 Engine","OptionCode":"1008054"},{"OptionGroup":null,"OptionGroupID":0,"OptionDisplayName":"4 Speed Transmission","OptionCode":"1007678"},{"OptionGroup":null,"OptionGroupID":0,"OptionDisplayName":"6 Cylinder Engine","OptionCode":"1006735"},{"OptionGroup":null,"OptionGroupID":0,"OptionDisplayName":"AMX Big Bad Package","OptionCode":"1005249"},{"OptionGroup":null,"OptionGroupID":0,"OptionDisplayName":"Amx/javelin SST Go Package 390","OptionCode":"1007251"},{"OptionGroup":null,"OptionGroupID":0,"OptionDisplayName":"Factory Air Conditioning","OptionCode":"1006048"},{"OptionGroup":null,"OptionGroupID":0,"OptionDisplayName":"Javelin SST Big Bad Package","OptionCode":"1008355"}]}
编写的Dart实体类如下,但始终无法解析数据并抛出错误:
class ClassicCarsOptionsModel { List<GetOptionsResult>? getOptionsResult; ClassicCarsOptionsModel({this.getOptionsResult}); ClassicCarsOptionsModel.fromJson(Map<String, dynamic> json) { if (json['GetOptionsResult'] != null) { getOptionsResult = <GetOptionsResult>[]; json['GetOptionsResult'].map((v) { getOptionsResult!.add(new GetOptionsResult.fromJson(v)); }); } } Map<String, dynamic> toJson() { final Map<String, dynamic> data = new Map<String, dynamic>(); if (this.getOptionsResult != null) { data['GetOptionsResult'] = this.getOptionsResult!.map((v) => v.toJson()).toList(); } return data; } } class GetOptionsResult { String? optionGroup; int? optionGroupID; String? optionDisplayName; String? optionCode; GetOptionsResult( {this.optionGroup, this.optionGroupID, this.optionDisplayName, this.optionCode}); GetOptionsResult.fromJson(Map<String, dynamic> json) { optionGroup = json['OptionGroup']; optionGroupID = json['OptionGroupID']; optionDisplayName = json['OptionDisplayName']; optionCode = json['OptionCode']; } Map<String, dynamic> toJson() { final Map<String, dynamic> data = new Map<String, dynamic>(); data['OptionGroup'] = this.optionGroup; data['OptionGroupID'] = this.optionGroupID; data['OptionDisplayName'] = this.optionDisplayName; data['OptionCode'] = this.optionCode; return data; } }
核心问题定位
代码存在一个致命逻辑错误:
在ClassicCarsOptionsModel.fromJson方法中,json['GetOptionsResult'].map()是延迟执行的惰性操作,若不调用.toList()或触发执行的方法,映射逻辑根本不会运行,最终getOptionsResult会是空列表,后续使用时必然抛出空指针或数据缺失类错误。
此外还有一个潜在风险:GetOptionsResult的optionGroup字段定义为String?,JSON中对应值是null虽无问题,但如果后续JSON返回非String类型值,会触发类型不匹配错误。
修复后的代码
方案1:改用forEach(逻辑更直观)
ClassicCarsOptionsModel.fromJson(Map<String, dynamic> json) { if (json['GetOptionsResult'] != null) { getOptionsResult = <GetOptionsResult>[]; json['GetOptionsResult'].forEach((v) { getOptionsResult!.add(GetOptionsResult.fromJson(v)); }); } }
方案2:保留map并添加toList()强制执行
ClassicCarsOptionsModel.fromJson(Map<String, dynamic> json) { if (json['GetOptionsResult'] != null) { getOptionsResult = json['GetOptionsResult'] .map<GetOptionsResult>((v) => GetOptionsResult.fromJson(v)) .toList(); } }
精准定位崩溃的技巧
- 查看错误栈日志:Dart会输出明确的崩溃行号和原因(如空指针、类型不匹配),直接定位出错位置。
- 分步打印调试:在
fromJson中添加打印语句,输出json['GetOptionsResult']的类型、内容,以及每个子对象v的结构,确认数据传递是否正常。 - 对比自动生成的实体类:用JSON转Dart工具生成标准实体类,与自己编写的类对比,排查字段名、类型是否匹配。
- 强化空安全校验:对可能为null的字段添加非空判断,避免
!滥用导致空指针。
内容的提问来源于stack exchange,提问作者Swapnil Gaikwad
相关产品推荐
相关产品推荐

