Flutter调用带请求头请求体的GET API:非流式响应及模型存储方案
问题分析与解决方案
你的代码存在两个核心问题导致无法正确存储响应:
- Stream只能被消费一次:
response.stream是单订阅流,第一次调用await response.stream.bytesToString()后,流就被耗尽了,后续再调用这个方法只会得到空内容。 - 错误添加Future到列表:
response.stream.bytesToString()返回的是Future<String>,你直接把这个Future对象添加到dataList,而不是等待它完成后拿到的实际字符串数据。
方案一:获取完整响应后存入模型
如果接口返回的是完整JSON数据(非分块流式输出),可以先拿到完整响应字符串,再解析为模型对象:
List<YourModel> dataList = []; StreamController<List<YourModel>> dataC = StreamController(); var headers = { 'CustomAuthentication': '', 'Content-Type': 'application/json', 'Cookie': 'cookie' }; var request = http.Request('GET', Uri.parse('url')); request.body = json.encode({ "data_value": "val" }); request.headers.addAll(headers); http.StreamedResponse response = await request.send(); if (response.statusCode == 200) { // 仅调用一次bytesToString获取完整响应 String responseBody = await response.stream.bytesToString(); print(responseBody); // 解析JSON为模型列表(假设接口返回数组格式) List<dynamic> jsonList = json.decode(responseBody); dataList = jsonList.map((json) => YourModel.fromJson(json)).toList(); // 将模型列表添加到StreamController dataC.add(dataList); // 打印验证模型数据 for(var model in dataList) { print(model.toString()); } } else { print(response.reasonPhrase); } // 返回解析后的模型列表 return dataList;
注意:需要提前定义YourModel类,并实现fromJson构造方法完成JSON到模型的转换
方案二:流式处理响应(适配分块输出接口)
如果接口是分块流式返回数据(比如逐段输出JSON或文本),可以监听流的每一段数据并逐步处理:
List<YourModel> dataList = []; StreamController<List<YourModel>> dataC = StreamController(); var headers = { 'CustomAuthentication': '', 'Content-Type': 'application/json', 'Cookie': 'cookie' }; var request = http.Request('GET', Uri.parse('url')); request.body = json.encode({ "data_value": "val" }); request.headers.addAll(headers); http.StreamedResponse response = await request.send(); if (response.statusCode == 200) { // 监听流的每一段数据,先转成UTF-8字符串 response.stream.transform(utf8.decoder).listen((chunk) { print('收到分块数据:$chunk'); // 解析当前分块的JSON(需根据实际分块格式调整逻辑) dynamic jsonData = json.decode(chunk); YourModel model = YourModel.fromJson(jsonData); dataList.add(model); // 每次添加后更新StreamController的数据流 dataC.add(List.from(dataList)); }, onDone: () { print('流处理完成'); dataC.close(); }, onError: (error) { print('流处理错误:$error'); dataC.addError(error); }); } else { print(response.reasonPhrase); }
额外注意事项
- 不再使用
StreamController时务必调用close(),避免内存泄漏。 - 如果在Flutter中使用,建议配合
StreamBuilder监听dataC.stream,实现UI的实时更新。
内容的提问来源于stack exchange,提问作者Jaini Shah
相关产品推荐
相关产品推荐

