Flutter如何将字符串转为Map<int,dynamic>?API返回格式是否有误?
首先判断API格式问题
你当前的API响应格式确实存在设计缺陷:
answer_selected字段返回的是不符合JSON规范的字符串,而非原生JSON对象:标准JSON要求对象的键必须用双引号包裹,且对象类型值不能被额外加引号转成纯字符串。你现在Laravel端应该是错误地将数组做了字符串化处理,才会返回"{1:\"True\",2:\"False\"}"这类值。- 额外说明:标准JSON本身不支持整数类型的对象键,即使后端返回正确的对象结构,键序列化后也会是字符串类型,客户端解析时做一次类型转换即可,不需要在后端提前转成字符串。
最优解决方案:调整Laravel端返回逻辑
优先在后端修正格式,避免客户端做高风险的字符串解析,稳定性最高:
- 不要将
answer_selected对应的数组做toString()类的字符串转换,直接将数组作为字段值返回,框架会自动序列化为标准JSON结构,正确返回示例如下:
{ "answer_selected": { "1": "True", "2": "False" } }
- 如果该字段是存在数据库的JSON类型字段,直接存数组结构、不要存字符串化的内容,接口返回时无需额外处理,Laravel会自动完成标准JSON序列化。
临时兼容方案:Flutter端解析非标准字符串
如果暂时无法修改后端接口,可以在Flutter端通过格式修正+解析的方式拿到Map<int, dynamic>类型结果,步骤如下:
- 取出
answer_selected对应的原始字符串值 - 通过正则替换给无引号的数字键补上双引号,修正为合法JSON格式
- 用内置的JSON解析工具处理后,将字符串键转换为int类型即可
对应实现代码:
import 'dart:convert'; Map<int, dynamic> convertAnswerMap(String rawContent) { // 修正非标准JSON,给数字键补充双引号 final validJsonStr = rawContent.replaceAllMapped( RegExp(r'(\d+):'), (match) => '"${match.group(1)}":' ); // 解析为基础Map结构 final tempMap = jsonDecode(validJsonStr) as Map<String, dynamic>; // 键转int后返回目标类型 return tempMap.map((k, v) => MapEntry(int.parse(k), v)); }
在模型类的fromJson序列化方法中直接调用该工具方法即可:
factory Question.fromJson(Map<String, dynamic> json) { return Question( answerSelected: convertAnswerMap(json['answer_selected'] as String), // 其他字段初始化逻辑 ); }
注意:客户端硬解析非标准字符串的方案容错率极低,只要后端返回的字符串格式出现微小变动(比如多余空格、值内包含数字加冒号的内容)就会解析失败,仅作为临时兼容方案使用,长期使用必须修正后端返回格式。
内容的提问来源于stack exchange,提问作者Hafiz
相关产品推荐
相关产品推荐

