Flutter中如何解析API返回的嵌套JSON对象提取message字段值
问题根因
接口返回的data字段不是结构化JSON对象,是被序列化为字符串的嵌套JSON结构。你之前直接将该字段按String类型接收后没有做二次解码,要么无法读取内部message字段,要么强行按对象解析会触发空值报错。
解决方案
分两步修改即可:
第一步:调整NotificationModel模型类
新增专门存储通知内容的message字段,在模型反序列化阶段自动完成嵌套字符串的二次解析,直接提取目标值,修改后的完整模型代码如下:
import 'dart:convert'; List<NotificationModel> notificationModelFromJson(String str) => List<NotificationModel>.from(json.decode(str).map((x) => NotificationModel.fromJson(x))); String notificationModelToJson(List<NotificationModel> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson()))); class NotificationModel { NotificationModel({ this.id, this.type, this.notifiableType, this.notifiableId, this.data, this.message, this.readAt, this.createdAt, this.updatedAt, }); double id; String type; String notifiableType; int notifiableId; String data; String message; DateTime readAt; DateTime createdAt; DateTime updatedAt; factory NotificationModel.fromJson(Map<String, dynamic> json) { // 二次解析data字段内的JSON字符串 final rawDataStr = json["data"] ?? ""; String parsedMessage = ""; try { final nestedData = jsonDecode(rawDataStr); parsedMessage = nestedData["message"] ?? ""; } catch (e) { // 兜底:如果data不是标准JSON格式,直接用原始字符串 parsedMessage = rawDataStr; } return NotificationModel( id: json["id"].toDouble(), type: json["type"], notifiableType: json["notifiable_type"], notifiableId: json["notifiable_id"], data: json["data"], message: parsedMessage, // 兼容空值场景,避免parse报错 readAt: json["read_at"] != null ? DateTime.parse(json["read_at"]) : null, createdAt: DateTime.parse(json["created_at"]), updatedAt: DateTime.parse(json["updated_at"]), ); } Map<String, dynamic> toJson() => { "id": id, "type": type, "notifiable_type": notifiableType, "notifiable_id": notifiableId, "data": data, "message": message, "read_at": readAt?.toIso8601String(), "created_at": createdAt.toString(), "updated_at": updatedAt.toString(), }; }
第二步:修改UI层的取值逻辑
找到列表项中渲染通知内容的Text组件,将原来直接渲染data.data的逻辑替换为读取提前解析好的message字段即可,对应代码修改如下:
// 原代码 // Text( // data.data, // style: TextStyle( // fontSize: 12, // color: Colors.black, // fontWeight: FontWeight.bold), // ), // 替换为 Text( data.message, maxLines: 3, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 12, color: Colors.black, fontWeight: FontWeight.bold), ),
注意点
- 不要对已经是字符串格式的
data字段调用jsonEncode,提取内部字段必须用jsonDecode做二次解码 - 所有调用
DateTime.parse的位置建议加空值判断,避免接口对应字段返回null时直接抛出解析异常 - 嵌套JSON解析逻辑必须加try-catch兜底,兼容个别通知data字段格式不符合预期的场景,避免页面整体崩溃
内容的提问来源于stack exchange,提问作者Ijaz Ahmed
相关产品推荐
相关产品推荐

