Flutter中HTTP请求数据转List对象始终为空问题求助
Flutter HTTP请求获取数据后List始终为空的问题排查与解决
问题描述
我是Flutter新手,具备C#开发背景。在通过HTTP请求获取站点数据并转换为List<Stations>对象时,尽管响应体包含有效数据,但List始终为空。调试阶段可观察到响应体中的内容,相关实现代码如下:
HttpService代码
class HttpService { final String url = "url hidden"; final String host = 'url hidden'; final String apiSegment = "api/"; // ignore: non_constant_identifier_names void login(email, password) async { try { Map<String, String> body = { 'username': email, 'password': password, }; Map<String, String> headers = {'Content-Type': 'application/json'}; final msg = jsonEncode(body); Response response = await post(Uri.parse("$url/Login"), headers: headers, body: msg); if (response.statusCode == 200) { var data = jsonDecode(response.body.toString()); print(data['jwtToken']); print('Login successfully'); final prefs = await SharedPreferences.getInstance(); await prefs.setString('jwtToken', data['jwtToken']); List<Stations> stationData = await getStationData('11'); var test = stationData; } else { print('failed'); } } catch (e) { print(e.toString()); } } Future<List<Stations>> getStationData(String stationId) async { final prefs = await SharedPreferences.getInstance(); final String? token = prefs.getString('jwtToken'); const String path = 'Station/GetAllStationData'; final uri = Uri.parse('$url/api/$path') .replace(queryParameters: {'stationId': stationId}); List<Stations> stationData = <Stations>[]; try { Response res = await get(uri, headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', // 'Authorization': 'Bearer $token', }); if (res.statusCode == 200) { var body = jsonDecode(res.body); var body2 = body.toString(); stationData = body .map( (dynamic item) => Stations.fromJson(item), ) .toList(); } else { throw "Unable to retrieve posts."; } } catch (e) { print(e.toString()); } return stationData; } }
调用方式
List<Stations> stationData = await getStationData('11');
响应体结构
响应体为外层包含data字段的JSON对象,data字段对应站点数据数组(示例结构如下):
{ "data": [ {"id": "1", "name": "站点1", ...}, {"id": "2", "name": "站点2", ...} ] }
问题原因
直接对jsonDecode(res.body)返回的整个JSON对象调用map方法,但该对象并非数组,而是包含data数组的外层对象。这种操作会触发异常,被catch块捕获后,最终返回初始的空列表。
解决方案
1. 修正数据转换逻辑
在解析响应体时,先提取data字段对应的数组,再进行对象转换:
if (res.statusCode == 200) { var body = jsonDecode(res.body); // 提取data字段的数组 var stationJsonList = body['data'] as List; stationData = stationJsonList .map((dynamic item) => Stations.fromJson(item)) .toList(); }
2. 增强错误排查能力
在catch块中打印详细错误信息,方便定位问题:
catch (e, stackTrace) { print('获取站点数据异常: $e'); print('异常堆栈: $stackTrace'); }
3. 验证Stations.fromJson方法
确保Stations类的fromJson方法正确映射JSON字段,尤其是注意C#习惯的PascalCase和Dart小驼峰命名的差异。推荐使用json_annotation包自动生成序列化代码,避免手动映射出错:
- 添加依赖:
json_annotation: ^4.8.1、build_runner: ^2.4.4、json_serializable: ^6.7.1 - 定义Stations类并添加注解:
import 'package:json_annotation/json_annotation.dart'; part 'stations.g.dart'; @JsonSerializable() class Stations { final String id; final String name; // 其他字段... Stations({required this.id, required this.name, ...}); factory Stations.fromJson(Map<String, dynamic> json) => _$StationsFromJson(json); Map<String, dynamic> toJson() => _$StationsToJson(this); }
- 运行命令生成序列化代码:
flutter pub run build_runner build
4. 其他注意事项
- 如果接口需要身份验证,取消
Authorization头的注释,确保token正确传递:'Authorization': 'Bearer $token' - 调试时可打印
body['data']的内容,确认数组结构和字段是否符合预期。
内容的提问来源于stack exchange,提问作者dotnetdevcsharp
相关产品推荐
相关产品推荐

