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

Flutter中HTTP GET请求返回null问题排查与解决

问题排查与解决方案

核心问题分析

  • JSON字段不匹配:返回的JSON根字段是"client"(单数),但Client模型的fromJson方法里读取的是"clients"(复数),导致解析后clients列表始终为null。
  • API解析逻辑错误:fetchClient函数错误地将整个响应数据当成数组遍历,实际响应是一个包含client数组的对象,遍历逻辑完全错误。
  • FutureBuilder未处理状态:直接访问snapshot.data.length,没有判断snapshot是否完成、是否有数据,当请求未完成或解析失败时,snapshot.data为null,触发NoSuchMethodError。

分步修复

1. 修正Client模型的JSON字段匹配

修改Client类的fromJson方法,将json['clients']改为json['client'],对应返回的JSON根字段:

class Client {
  List<Clients>? clients;

  Client({required this.clients});

  Client.fromJson(Map<String, dynamic> json) {
    if (json['client'] != null) { // 从clients改为client,匹配返回的JSON字段
      clients = <Clients>[];
      json['client'].forEach((v) {
        clients?.add(new Clients.fromJson(v));
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    if (this.clients != null) {
      data['clients'] = this.clients!.map((v) => v.toJson()).toList();
    }
    return data;
  }
}

2. 重构API调用逻辑

整个响应对应一个Client对象,里面包含List<Clients>,调整函数返回类型并修正解析逻辑:

Future<Client> fetchClient() async {
  Uri url = Uri.parse("${BASE_URL}client");

  var response = await http.get(url, headers: <String, String>{
    'Content-Type': 'application/json; charset=UTF-8',
    'Authorization': 'Bearer $TOKEN',
  });

  if (response.statusCode == 200) {
    var data = json.decode(response.body);
    return Client.fromJson(data); // 直接用模型的fromJson解析整个响应
  } else {
    throw Exception('Failed to load clients');
  }
}

3. 修复FutureBuilder的状态处理

在builder中先判断snapshot的状态,处理加载中、错误、无数据的情况,再安全访问数据:

return FutureBuilder<Client>(
  future: fetchClient(),
  builder: (context, AsyncSnapshot<Client> snapshot) {
    if (snapshot.connectionState == ConnectionState.waiting) {
      return const Center(child: CircularProgressIndicator());
    } else if (snapshot.hasError) {
      return Center(child: Text('Error: ${snapshot.error}'));
    } else if (!snapshot.hasData || snapshot.data?.clients == null || snapshot.data!.clients!.isEmpty) {
      return const Center(child: Text('No clients found'));
    } else {
      return ListView.builder(
          itemCount: snapshot.data!.clients!.length,
          itemBuilder: (context, index) {
            final client = snapshot.data!.clients![index];
            return ListTile(
              title: Text(client.name ?? 'Unknown'),
              subtitle: Text(client.address ?? 'No address'),
            );
          });
    }
  },
);

额外优化建议

  • 模型命名优化:把Clients改为ClientItem,避免和外层Client类混淆,减少代码歧义。
  • 使用json_serializable包自动生成JSON解析代码,避免手动编写时的字段匹配错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 20:11:09