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

REST API映射结果返回Null?Flutter接口数据解析问题排查

为什么我的Flutter控制器返回的数据为Null?

我编写了如下控制器代码,但返回的数据始终为Null。尝试过将jsonData和data转换为列表格式,问题依然存在。是不是我的模型与控制器的映射有问题?模型包含多个嵌套类,由app.quicktype.io根据API的JSON响应生成,响应内容过长无法粘贴。

控制器代码

Future<List<GetEntityKindsModel>> getEntityKinds() async
{
  List<GetEntityKindsModel> data = [];
 try
     {
      dynamic response = await http.get(Uri.parse(url));
      dynamic jsonData = jsonDecode(response.body);
      data = jsonData.map((item)=>GetEntityKindsModel.fromJson(item));
      print('Data -- $data');
     }
     catch(e)
  {
    print('Error -- $e');
  }
  return data;
}

打印语句截图

打印语句截图

模型代码

class GetEntityKindsModel {
  GetEntityKindsModel({
    required this.name,
    required this.type,
    required this.classType,
    required this.label,
    required this.pluralLabel,
    this.sharedVisibility,
    this.subscribe,
    required this.id,
    this.entityName,
    required this.parentEntityId,
    required this.languageId,
    this.timestamp,
    this.tagText,
    required this.entityIndex,
    this.code,
    this.blobKey,
  });

  String name;
  Type type;
  ClassType classType;
  String label;
  String pluralLabel;
  String? sharedVisibility;
  Subscribe? subscribe;
  int id;
  String? entityName;
  int parentEntityId;
  LanguageId languageId;
  int? timestamp;
  String? tagText;
  List<String> entityIndex;
  Code? code;
  BlobKey? blobKey;

  factory GetEntityKindsModel.fromJson(Map<String, dynamic> json) => GetEntityKindsModel(
    name: json["name"],
    type: typeValues.map[json["type"]]!,
    classType: classTypeValues.map[json["classType"]]!,
    label: json["label"],
    pluralLabel: json["pluralLabel"],
    sharedVisibility: json["sharedVisibility"],
    subscribe: subscribeValues.map[json["subscribe"]]!,
    id: json["id"],
    entityName: json["entityName"],
    parentEntityId: json["parentEntityId"],
    languageId: languageIdValues.map[json["languageId"]]!,
    timestamp: json["timestamp"],
    tagText: json["tagText"],
    entityIndex: List<String>.from(json["entityIndex"].map((x) => x)),
    code: json["code"] == null ? null : Code.fromJson(json["code"]),
    blobKey: json["blobKey"] == null ? null : BlobKey.fromJson(json["blobKey"]),
  );

  Map<String, dynamic> toJson() => {
    "name": name,
    "type": typeValues.reverse[type],
    "classType": classTypeValues.reverse[classType],
    "label": label,
    "pluralLabel": pluralLabel,
    "sharedVisibility": sharedVisibility,
    "subscribe": subscribeValues.reverse[subscribe],
    "id": id,
    "entityName": entityName,
    "parentEntityId": parentEntityId,
    "languageId": languageIdValues.reverse[languageId],
    "timestamp": timestamp,
    "tagText": tagText,
    "entityIndex": List<dynamic>.from(entityIndex.map((x) => x)),
    "code": code?.toJson(),
    "blobKey": blobKey?.toJson(),
  };
}

class BlobKey {
  BlobKey({
    required this.blobKey,
  });

  String blobKey;

  factory BlobKey.fromJson(Map<String, dynamic> json) => BlobKey(
    blobKey: json["blobKey"],
  );

  Map<String, dynamic> toJson() => {
    "blobKey": blobKey,
  };
}

enum ClassType { STATIC, NULL, DYNAMIC }

final classTypeValues = EnumValues({
  "dynamic": ClassType.DYNAMIC,
  "null": ClassType.NULL,
  "static": ClassType.STATIC
});

class Code {
  Code({
    required this.value,
  });

  String value;

  factory Code.fromJson(Map<String, dynamic> json) => Code(
    value: json["value"],
  );

  Map<String, dynamic> toJson() => {
    "value": value,
  };
}

enum LanguageId { EN_US }

final languageIdValues = EnumValues({
  "en_US": LanguageId.EN_US
});

enum Subscribe { YES, EMPTY }

final subscribeValues = EnumValues({
  "": Subscribe.EMPTY,
  "yes": Subscribe.YES
});

enum Type { PRIMARY, RELATED }

final typeValues = EnumValues({
  "PRIMARY": Type.PRIMARY,
  "RELATED": Type.RELATED
});

class EnumValues<T> {
  Map<String, T> map;
  late Map<T, String> reverseMap;

  EnumValues(this.map);

  Map<T, String> get reverse {
    reverseMap = map.map((k, v) => MapEntry(v, k));
    return reverseMap;
  }
}

问题排查与解决

  1. 类型转换缺失:jsonData.map()返回的是Iterable类型,不能直接赋值给List<GetEntityKindsModel>,必须调用.toList()完成转换:

    data = jsonData.map((item)=>GetEntityKindsModel.fromJson(item)).toList();
    

    原代码未做此转换,导致类型不匹配,data未被正确赋值。

  2. 枚举空安全隐患:模型中枚举转换使用!强制解包,若API返回的枚举值不在映射范围内,会直接抛出异常进入catch块,导致data保持初始空列表。建议添加空值判断并设置默认值:

    type: typeValues.map[json["type"]] ?? Type.PRIMARY,
    

    避免因枚举值不匹配引发崩溃。

  3. API响应结构验证:确认API返回的是数组格式JSON。如果响应外层包含对象(如{"data": [...]}),需先提取数组部分:

    dynamic jsonData = jsonDecode(response.body);
    List<dynamic> listData = jsonData["data"];
    data = listData.map((item)=>GetEntityKindsModel.fromJson(item)).toList();
    

    可先打印jsonData的结构,确认是否为直接数组。

  4. 异常信息优化:当前catch块仅打印简单错误,建议改为print('Error -- ${e.toString()}'),获取更详细的错误堆栈,便于定位问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 08:47:49