Flutter解析API数据时DeviceClass实例字段为空问题
问题诊断与解决方案
常见原因1:数据模型类的JSON字段映射错误
这是最普遍的问题:要么模型类字段名和API返回的JSON键名不匹配,要么没正确使用序列化注解(如json_serializable)。
错误示例:
class DeviceClass { String? deviceId; String? deviceName; DeviceClass({this.deviceId, this.deviceName}); // 错误:API返回的键是"device_id",这里却用了"deviceId" factory DeviceClass.fromJson(Map<String, dynamic> json) { return DeviceClass( deviceId: json['deviceId'], deviceName: json['deviceName'], ); } }
修正方案:
- 用
@JsonKey注解映射不同命名规则的键,同时配合json_serializable生成正确的解析代码:
import 'package:json_annotation/json_annotation.dart'; part 'device_class.g.dart'; @JsonSerializable() class DeviceClass { @JsonKey(name: 'device_id') // 匹配API返回的下划线命名键 String? deviceId; @JsonKey(name: 'device_name') String? deviceName; DeviceClass({this.deviceId, this.deviceName}); factory DeviceClass.fromJson(Map<String, dynamic> json) => _$DeviceClassFromJson(json); Map<String, dynamic> toJson() => _$DeviceClassToJson(this); }
- 运行代码生成命令:
flutter pub run build_runner build
常见原因2:手动解析时遗漏字段或类型不匹配
如果没用序列化工具,手动写fromJson时容易出现两种问题:一是漏写字段赋值,二是JSON字段类型和模型类定义不一致(比如API返回int类型的deviceId,模型类却定义成String?)。
检查点:
- 逐行对比API返回的JSON键名、类型和模型类字段,确保完全对应。
- 确认
fromJson方法里每个字段都正确赋值,没有拼写错误。
常见原因3:API返回的JSON结构嵌套问题
如果API返回的是嵌套JSON(比如{"data": {"deviceId": "xxx", ...}}),但你直接把整个JSON对象传给fromJson,而非内层的data对象,就会导致字段为null。
错误示例:
// API返回:{"code":200,"data":{"deviceId":"123"}} var responseJson = jsonDecode(response.body); DeviceClass device = DeviceClass.fromJson(responseJson); // 错误:应该取responseJson['data']
修正:
var responseJson = jsonDecode(response.body); DeviceClass device = DeviceClass.fromJson(responseJson['data']); // 传入嵌套的data对象
常见原因4:打印实例的方式误导
直接print(device)显示Instance of DeviceClass是正常现象,这是Dart默认的实例打印行为。要验证字段是否有值,要么重写toString方法,要么直接打印具体字段:
// 重写toString方法 class DeviceClass { // ... 其他代码 @override String toString() { return 'DeviceClass(deviceId: $deviceId, deviceName: $deviceName)'; } } // 或者直接打印字段 print('设备ID:${device.deviceId}');
排查步骤总结
- 核对API返回JSON的键名、类型与模型类字段是否完全匹配,注意嵌套结构层级。
- 使用
json_serializable时,确保注解正确并运行了代码生成命令。 - 解析时传入正确的JSON层级(比如嵌套的
data字段)。 - 通过重写
toString或直接打印字段验证数据,而非仅打印实例本身。
内容的提问来源于stack exchange,提问作者Mackina
相关产品推荐
相关产品推荐

