Qt解析网络返回的JSON数组时无法进入foreach循环是何原因?
核心问题原因
- 解析JSON时未校验返回数据结构,直接强制将QJsonDocument转为QJsonArray。
- 按RESTful接口常规设计,
/tili/1为单条账户资源查询接口,服务端返回的响应通常为单个JSON对象,而非包含多条记录的JSON数组。当文档实际为对象格式时,调用json_doc.array()会返回空数组,导致foreach循环无匹配元素,完全不会进入循环体。 - 未校验网络请求的错误状态,若服务端返回HTML错误页、非JSON格式的错误响应,
QJsonDocument会解析为无效文档,转换出的数组同样为空,触发上述问题。
修正后的实现代码
void engine::saldoReplySlot(QNetworkReply *saldoreply){ // 优先校验请求状态,出错直接终止流程 if(saldoreply->error() != QNetworkReply::NoError){ qDebug() << "请求异常:" << saldoreply->errorString(); saldoreply->deleteLater(); return; } QByteArray response_data = saldoreply->readAll(); qDebug() << "原始返回内容:" << response_data; QJsonDocument json_doc = QJsonDocument::fromJson(response_data); QString saldo; // 先判断实际JSON结构,再做对应解析 if(json_doc.isArray()){ QJsonArray json_array = json_doc.array(); foreach(const QJsonValue &value, json_array){ QJsonObject json_object = value.toObject(); saldo += QString::number(json_object["idtili"].toInt()) + " " + json_object["tilin_saldo"].toString() + "\r\n"; qDebug() << "loopissa"; } } else if(json_doc.isObject()){ // 单资源接口返回单个对象的场景,直接解析即可 QJsonObject json_object = json_doc.object(); saldo += QString::number(json_object["idtili"].toInt()) + " " + json_object["tilin_saldo"].toString() + "\r\n"; } else { qDebug() << "返回内容非合法JSON结构"; } qDebug() << "lähetetään signaali exelle missä saldo on"; emit saldoToExe(saldo); qDebug() << saldo; // 仅需对入参的reply指针执行一次释放,避免重复释放 saldoreply->deleteLater(); }
其他注意事项
- 原代码中
saldoReply指针与槽函数入参的saldoreply指向完全相同的QNetworkReply对象,连续对两个指针调用deleteLater会造成重复释放内存,引发程序崩溃。 - 无需每次发起网络请求都新建
QNetworkAccessManager实例,可复用全局单例的网络管理器,降低资源开销。 - 直接对照调试日志打印的原始返回内容,即可快速确认服务端返回的JSON结构,无需额外猜测。
内容的提问来源于stack exchange,提问作者veeqq
相关产品推荐
相关产品推荐

