Flutter使用Dio调用API返回带query的JSON时出现FormatException如何解决
问题原因
- 前端数据解析逻辑本身无错误,报错根源为后端返回的响应格式不符合JSON规范:从错误日志可见,正常业务JSON结束位置
"employeeId":2900}之后直接拼接了另一段SQL报错的JSON结构{"message":"SQLSTATE[22001]: String ...,两段JSON无分隔符,导致Dio解析失败抛出格式异常。 - 「无query字段时正常、携带query字段时报错」为触发条件的表象:后端开启SQL调试模式返回query字段时,同时触发了数据库超长字符串截断错误,额外输出了报错JSON,才导致异常出现。
修复方案
后端修复(根本解决)
- 调整API响应逻辑,关闭不必要的SQL调试日志输出,或将所有错误信息统一纳入标准响应的指定字段内,保证响应体始终为单段合法JSON。
- 修复
SQLSTATE[22001]报错对应的数据库逻辑:该报错为插入/查询的字符串长度超过了数据库字段的定义上限,检查对应业务的字段读写规则即可。
前端临时兼容方案(仅做应急使用,不建议长期落地)
若暂时无法调整后端逻辑,可在Dio中自定义响应转换器,只截取第一段合法JSON做解析,代码如下:
import 'dart:convert'; import 'package:dio/dio.dart'; Future<List<ListAlbum>> listData() async { final token = 'my_api_token'; String url = 'https://...com/api/requestedCertificateList?token=${token}'; Dio dio = Dio(); // 新增自定义JSON解析逻辑,截取第一段合法JSON dio.transformer = BackgroundTransformer() ..jsonDecodeCallback = (String responseStr) { int bracketCount = 0; int validEndIndex = 0; for (int i = 0; i < responseStr.length; i++) { if (responseStr[i] == '{') bracketCount++; if (responseStr[i] == '}') { bracketCount--; if (bracketCount == 0) { validEndIndex = i; break; } } } return jsonDecode(responseStr.substring(0, validEndIndex + 1)); }; dio.options.headers['Content-Type'] = 'application/json'; final body = {'limit': 1, 'orderBy': 'idCertificateRequest', 'orderType': 'DESC'}; final response = await dio.post(url, data: body); if (response.statusCode == 200) { return response.data["data"]["data"] .map<ListAlbum>((json) => ListAlbum.fromJson(json)) .toList(); } else { throw Exception('Failed!'); } }
内容的提问来源于stack exchange,提问作者Fozuda
相关产品推荐
相关产品推荐

