Qt中JSON转QVariantMap时数值类型丢失问题求助
解决方案
Qt的QJsonObject::toVariantMap()方法在转换数值类型时,会将QJsonValue的Int类型转成QVariant(int),Double类型转成QVariant(double)。问题核心是:Qt解析JSON时,会把无小数部分的数值(如3)识别为Int类型,带小数部分的(包括3.0)识别为Double类型——但默认的toVariantMap()无法帮你严格保留原始JSON的数值类型(比如3.0会被当成整数处理)。
要解决这个问题,不能直接用默认转换方法,需要手动遍历JSON结构,按QJsonValue的原始解析类型转换为QVariant:
实现自定义类型转换函数
写一个递归处理的辅助函数,确保每个数值类型都保留原始解析结果:
QVariant jsonValueToVariant(const QJsonValue &value) { switch (value.type()) { case QJsonValue::Double: // 强制保留double类型,即使数值是整数形式(如3.0) return QVariant(value.toDouble()); case QJsonValue::Int: return QVariant(value.toInt()); case QJsonValue::Int64: return QVariant(value.toInt64()); // 兼容64位整数场景 case QJsonValue::Bool: return QVariant(value.toBool()); case QJsonValue::String: return QVariant(value.toString()); case QJsonValue::Array: { QVariantList variantList; for (const QJsonValue &item : value.toArray()) { variantList.append(jsonValueToVariant(item)); } return variantList; } case QJsonValue::Object: { QVariantMap variantMap; const QJsonObject &obj = value.toObject(); for (auto it = obj.constBegin(); it != obj.constEnd(); ++it) { variantMap.insert(it.key(), jsonValueToVariant(it.value())); } return variantMap; } case QJsonValue::Null: return QVariant(QMetaType::Nullptr); default: return QVariant(); } }
替换原有转换逻辑
把原来的toVariantMap()调用换成自定义函数:
QJsonParseError err; QJsonDocument body = QJsonDocument::fromJson(request->getRequest()->collectedData(), &err); if (err.error != QJsonParseError::NoError) { // 这里可添加错误处理,比如返回400错误响应 return; } // 用自定义函数转换,严格保留原始数值类型 QVariantMap userConfig = jsonValueToVariant(body.object()).toMap();
原理说明
- Qt解析
"almost_pi":3.0时,会将其识别为QJsonValue::Double类型,自定义函数会转为QVariant(double),后续序列化JSON时会输出3.0; - 解析
"pi":3.14时同样保留double类型; - 解析
"count":3时会识别为QJsonValue::Int,转为QVariant(int),序列化输出3,完全匹配原始JSON的类型。
这种方法不需要提前知晓字段类型,递归处理所有嵌套的JSON结构,确保所有数值类型严格保留。
内容的提问来源于stack exchange,提问作者Bloux
相关产品推荐
相关产品推荐

