Flutter调用API获取用户数据返回空数组,请求排查问题
问题排查与解决方案
核心问题分析
模型与API响应结构不匹配
- 后端返回的是直接的数组格式,但原
GlobalUser.fromJson试图读取json["users"]字段,导致无法解析到数据,最终返回空列表。 APIUser类中email字段定义为int?,但后端返回的是字符串类型邮箱,解析时会抛出异常,直接导致整个解析流程失败。
- 后端返回的是直接的数组格式,但原
请求逻辑错误
- 获取用户列表属于查询操作,通常使用
GET请求,但原代码用了POST,若后端仅接受GET会导致请求异常,print语句无法执行。 storage.read('token')是异步操作,原代码未加await,导致请求头中的Token值为Token Instance of 'Future<String?>',授权失败。
- 获取用户列表属于查询操作,通常使用
错误处理不完整
- 异常捕获仅用
log输出,在控制台不易察觉;非200/401/500的状态码无处理逻辑,请求失败时无法定位原因。
- 异常捕获仅用
修正后的代码
1. 模型代码修正
import 'dart:convert'; APIUser apiUserFromJson(String str) => APIUser.fromJson(json.decode(str)); String apiUserToJson(APIUser data) => json.encode(data.toJson()); class APIUser { APIUser({this.id, this.username, this.email, this.role}); int? id; String? username; String? email; // 修正为String类型,匹配后端返回 String? role; factory APIUser.fromJson(Map<String, dynamic> json) => APIUser( id: json["user"]["id"], username: json["user"]["username"], email: json["user"]["email"], role: json["user_role"], ); Map<String, dynamic> toJson() => { "id": id, "username": username, "email": email, "role": role, }; } // 直接解析后端返回的数组,无需GlobalUser包装 List<APIUser> globalUsersFromJson(String str) => List<APIUser>.from( json.decode(str).map((x) => APIUser.fromJson(x)), );
2. 获取数据方法修正
import 'package:http/http.dart' as http; import 'dart:io'; Future<List<APIUser>?> getGlobalUsers() async { try { var token = await storage.read('token'); // 添加await获取实际token值 if (token == null) { print('Token为空,授权失败'); return null; } final uri = Uri.parse("${ApiConstants.baseUrl}/get_users"); final headers = { HttpHeaders.contentTypeHeader: 'application/json', HttpHeaders.authorizationHeader: 'Token $token' }; // 改为GET请求,符合查询接口语义 var response = await http.get(uri, headers: headers); print('响应状态码: ${response.statusCode}'); print('响应体: ${response.body}'); // 打印完整响应体,方便排查 if (response.statusCode == 200) { return globalUsersFromJson(response.body); } else if (response.statusCode == 401) { print('未授权,请重新登录'); return null; } else if (response.statusCode >= 500) { print('服务器错误'); return null; } else { print('未知状态码: ${response.statusCode}'); return null; } } catch (e) { print('请求异常: $e'); // 用print替代log,确保控制台可见 return null; } }
额外排查点
- 确认项目网络权限:Android需在
AndroidManifest.xml添加<uses-permission android:name="android.permission.INTERNET"/>;iOS需在Info.plist中配置HTTP访问权限(若使用非HTTPS接口)。 - 核对
ApiConstants.baseUrl与Postman中的地址完全一致,避免拼写错误。 - 调用
getGlobalUsers时,需用await获取返回值,例如:var users = await getGlobalUsers(); print(users?.length);
内容的提问来源于stack exchange,提问作者user11319165
相关产品推荐
相关产品推荐

