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

解析服务器JSON遇‘String非Map<String,dynamic>子类型’错误,硬编码正常

问题描述

尝试从网络源解析JSON对象时遇到错误,已确认应用可从服务器获取数据,但模型设置可能存在问题。

服务器返回的JSON格式

{
    "neighborhood": 
    [
        {
            "houdeholdId": 1,
            "members":
            [
                {
                    "father": "John",
                    "mother": "Marry",
                    "child": "Mark"
                }
            ]
        },
        {
            "householdId": 2,
            "members":
            [
                {
                    "father": "Joseph",
                    "mother": "Anna",
                    "child": "Lisa"

                }
            ]
        }
    ]
}

该数据来自我用于测试的Postman服务器。

控制器文件代码

class Neighbors {
  late List<HouseHolds> _neighborhood;
  List<HouseHolds> get neighborhood=> _neighborhood;

  Neighbors({required neighborhood}){
    this._neighborhood = neighborhood;
  }

  Neighbors.fromJson(Map<String, dynamic> json) {
    if (json['neighborhood'] != null) {
    _neighborhood= <HouseHolds>[];
      json['neighborhood'].forEach((v) {
        _neighborhood!.add(HouseHolds.fromJson(v));
      });
    }
  }
}

Android Studio提示错误出在Neighbors.fromJson()函数,以下是我的数据获取与解析代码:

List<dynamic> _houseHolds = [];
List<dynamic> get houseHolds =>_houseHolds;

Future<void> getHouseHolds()async {

  // fetch and place data from server
  Response response = await houseHoldsRepo.getHouseHolds();   

  // successful fetch
  if(response.statusCode == 200){
    _houseHolds = [];

  // Unhandled Exception: type 'String' is not a subtype of type 'Map<String, dynamic>'
  _houseHolds.addAll(Neighbors.fromJson(response.body).neighborhood);

  update(); // refresh app
  }
}

奇怪的是,当我直接硬编码数据时,解析可以正常进行:

List<dynamic> _houseHolds = [];
List<dynamic> get houseHolds =>_houseHolds;

Future<void> getVendorList()async {

  // fetch and place data from server
  Response response = await houseHoldsRepo.getHouseHolds();   

  // successful fetch
  if(response.statusCode == 200){
    _houseHolds = [];

  // this works
  _houseHolds.addAll(Neighbors.fromJson({
  "neighborhood": 
  [
      {
          "houdeholdId": 1,
          "members":
          [
              {
                  "father": "John",
                  "mother": "Marry",
                  "child": "Mark"
              }
          ]
      },
      {
          "householdId": 2,
          "members":
          [
              {
                  "father": "Joseph",
                  "mother": "Anna",
                  "child": "Lisa"

              }
          ]
      }
  ]
}).neighborhood);
  update(); // refresh app
  }
}

请问我该如何正确解析服务器返回的JSON数据?


解决方法

核心问题

你遇到的type 'String' is not a subtype of type 'Map<String, dynamic>'错误,本质是直接把服务器返回的字符串格式JSON传给了需要Map类型的Neighbors.fromJson方法。硬编码时传入的是Dart原生Map对象,所以能正常解析,但网络请求返回的response.body是字符串,必须先转换成Map。

具体修复步骤

  1. 导入JSON解析包:在代码文件顶部添加dart:convert依赖
import 'dart:convert';
  1. 修改解析逻辑:将字符串格式的响应体转换成Map后再传入模型类
// 替换原解析代码行
final Map<String, dynamic> jsonData = json.decode(response.body);
_houseHolds.addAll(Neighbors.fromJson(jsonData).neighborhood);

额外优化建议

  • 修正JSON字段拼写错误:服务器返回的第一个对象字段是houdeholdId(少了一个s),第二个是householdId,这会导致HouseHolds.fromJson解析第一个对象时无法正确获取ID,建议统一字段名为householdId。
  • 简化模型类代码:用Dart构造器语法糖优化Neighbors类,提升可读性和安全性
class Neighbors {
  final List<HouseHolds> neighborhood;

  Neighbors({required this.neighborhood});

  factory Neighbors.fromJson(Map<String, dynamic> json) {
    final List<dynamic> neighborhoodList = json['neighborhood'] ?? [];
    final List<HouseHolds> households = neighborhoodList
        .map((item) => HouseHolds.fromJson(item))
        .toList();
    return Neighbors(neighborhood: households);
  }
}
  • 提升类型安全性:将_houseHolds的类型从List<dynamic>改为List<HouseHolds>,避免后续类型转换隐患
List<HouseHolds> _houseHolds = [];
List<HouseHolds> get houseHolds => _houseHolds;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 14:02:51