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

Flutter调用API时如何正确以JSON格式传递含嵌套结构的请求体数据?

正确传递JSON格式请求体的解决方案

问题根源分析

你现在的问题主要出在两个关键地方:

  1. 错误嵌套对象转字符串:weekends和weekdays本应是嵌套的JSON对象,但你用.toString()把它们转成了普通字符串,直接破坏了整个请求体的JSON结构,API收到后根本无法解析这些字段。
  2. 错误的JSON编码逻辑:jsonEncode(body.toString())属于双重编码(先把对象转成字符串,再对字符串二次编码),而且MultipartRequest.fields是用来传递键值对表单数据的,直接把整个JSON字符串塞进去会让请求格式完全不符合API预期。

解决方案步骤

1. 修正请求体构造,保留嵌套Map结构

首先要去掉weekends和weekdays后面的.toString(),让它们保持为Map类型,这样整个body就是一个合法的嵌套Map,后续才能正确编码为标准JSON:

// 修正后的请求体构造
dynamic body = {
  'doctor_availablity_done': StatusEnum.Yes.index.toString(),
  'emergency_call': emergencyCall,
  'weekends': { 
    "days": selectedWeekendList.toString(), 
    "time_period": { 
      "morning": { 
        "start_time": weekendMorningStart.value.toString(), 
        "end_time": weekendMorningEnd.value.toString() 
      }, 
      "afternoon": { 
        "start_time": weekendAfternoonStart.value.toString(), 
        "end_time": weekendAfternoonEnd.value.toString() 
      }, 
      "evening": { 
        "start_time": weekendEveningStart.value.toString(), 
        "end_time": weekendEveningEnd.value.toString() 
      }, 
      "night": { 
        "start_time": weekendNightStart.value.toString(), 
        "end_time": weekendNightStart.value.toString() 
      } 
    } 
  }, // 去掉.toString(),保留Map结构
  'weekdays': { 
    "days": selectedWeekdaysList.toString(), 
    "time_period": { 
      "morning": { 
        "start_time": weekdaysMorningStart.value.toString(), 
        "end_time": weekdaysMorningEnd.value.toString() 
      }, 
      "afternoon": { 
        "start_time": weekdaysAfternoonStart.value.toString(), 
        "end_time": weekdaysAfternoonEnd.value.toString() 
      }, 
      "evening": { 
        "start_time": weekdaysEveningStart.value.toString(), 
        "end_time": weekdaysEveningEnd.value.toString() 
      }, 
      "night": { 
        "start_time": weekdaysNightStart.value.toString(), 
        "end_time": weekdaysNightStart.value.toString() 
      } 
    } 
  }, // 去掉.toString(),保留Map结构
};

2. 选择正确的请求方式

根据你是否需要上传文件,分两种场景处理:

场景A:不需要上传文件(普通JSON请求)

如果只是传递JSON数据,不需要附带文件,直接使用http.post是最简洁的方案:

var headers = {
  'Authorization': 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczpcL1wvdG90YWxoZWFsdGhzb2x1dGlvbnMub3JnLmluXC9tZWRpY2FsLWRldlwvYXBpXC9kb2N0b3JcL2xvZ2luIiwiaWF0IjoxNjYwMDQyMzg3LCJleHAiOjE2NjAxMjg3ODcsIm5iZiI6MTY2MDA0MjM4NywianRpIjoiMzI2Y2xsNzEybElYaktqSyIsInN1YiI6MTYzLCJwcnYiOiIyM2JkNWM4OTQ5ZjYwMGFkYjM5ZTcwMWM0MDA4NzJkYjdhNTk3NmY3In0.5FbSnY-tPQMdyNFxdWmPuxCmQAPUcutejWkKPJT3XTE',
  'Content-Type': 'application/json' // 必须添加这个头部,告知API接收的是JSON格式
};

http.Response response = await http.post(
  Uri.parse(url),
  headers: headers,
  body: jsonEncode(body), // 直接对合法的嵌套Map进行JSON编码
);

if (response.statusCode == 200) {
  print(response.body);
} else {
  print(response.reasonPhrase);
}
场景B:需要上传文件(必须用MultipartRequest)

如果你确实需要用MultipartRequest(比如要同时上传文件和JSON数据),需要把JSON数据作为一个表单字段添加进去:

var headers = {
  'Authorization': 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczpcL1wvdG90YWxoZWFsdGhzb2x1dGlvbnMub3JnLmluXC9tZWRpY2FsLWRldlwvYXBpXC9kb2N0b3JcL2xvZ2luIiwiaWF0IjoxNjYwMDQyMzg3LCJleHAiOjE2NjAxMjg3ODcsIm5iZiI6MTY2MDA0MjM4NywianRpIjoiMzI2Y2xsNzEybElYaktqSyIsInN1YiI6MTYzLCJwcnYiOiIyM2JkNWM4OTQ5ZjYwMGFkYjM5ZTcwMWM0MDA4NzJkYjdhNTk3NmY3In0.5FbSnY-tPQMdyNFxdWmPuxCmQAPUcutejWkKPJT3XTE'
};

var request = http.MultipartRequest(
  'POST',
  Uri.parse(url)
);

// 将JSON数据作为一个表单字段添加
request.fields['data'] = jsonEncode(body);
// 如果需要上传文件,在这里添加:request.files.add(await http.MultipartFile.fromPath('file', '你的文件路径'));

request.headers.addAll(headers);
http.StreamedResponse response = await request.send();

if (response.statusCode == 200) {
  print(await response.stream.bytesToString());
} else {
  print(response.reasonPhrase);
}

注意:这种方式需要API端支持从表单字段读取JSON数据,如果API要求整个请求体是纯JSON,那还是用场景A的方案更合适。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 17:17:44