如何使用 QTcpSocket 发送 JSON

How to send JSON with QTcpSocket

本文关键字:JSON 发送 QTcpSocket 何使用      更新时间:2023-10-16

我可以将JSON对象从客户端发送到服务器,但无法从服务器上的JSON对象获取项目。

尝试了几个例子,当我研究时发现我无法解决问题。

发送 JSON 的代码:

QJsonObject levan{
    {"id",1},
    {"tipo","reforço"},
    {"ca", 10},
    {"cb",0},
    {"cc",0},
    {"cd",0},
    {"ce",0},
    {"cf",0},
    {"cg",0},
    {"ch",0},
};
QJsonArray jsarray {levan};
QJsonDocument jsDoc(jsarray);
QString jsString = QString::fromLatin1(jsDoc.toJson());
this->tcpSocket->write(jsString.toLatin1());

接收 JSON 的代码:

QString str = this->socket->readAll();
QJsonDocument jsonResponse = QJsonDocument::fromJson(str.toLatin1());
QJsonObject jsonObject = jsonResponse.object();
QJsonArray jsonArray = jsonObject["levantamento"].toArray();
qDebug()<< jsonResponse.object().value("levan");
if (jsonResponse.array().empty()) {
    qDebug() << "empty";
}

我可以将 JSON 显示为文本,但我无法从 JSON 中获取项目。

您正在创建一个QJsonObject,然后使用该对象创建QJsonArray。因此,最终输出是一个 JSON 对象,其中包含一个只有一个对象的嵌套数组。我不确定您是打算在数组中只有一个对象还是所有这些对象的数组。

而且,在请求中创建的 JSON 不是您尝试在响应中读取的内容。您的请求中没有关键levantamentolevan,因此您无法找到任何针对响应的内容。您需要处理请求 JSON 中的对象填充。以下示例使用一些测试数据进行请求填充和提取作为响应。希望对您有所帮助!

例:

#include <QDebug>
#include <QString>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
int main()
{
    // Request: Create JSON objects and array of objects
    const auto jArrKey = "levan";
    const auto jTstKey = "test";
    const auto jRqObj1 = QJsonObject{ { "id", 1 } };
    const auto jRqObj2 = QJsonObject{ { "cb", 0 } };
    const auto jRqObj3 = QJsonObject{ { "cc", 0 } };
    const auto jReqArr = QJsonArray{ jRqObj1, jRqObj2, jRqObj3 };
    const auto jTstObj = QJsonObject{ { "Hello", "World" } };
    const auto jReqObj = QJsonObject{ { jArrKey, jReqArr }, { jTstKey, jTstObj } };
    const auto jReqDoc = QJsonDocument{ jReqObj };
    const auto jReqStr = QString::fromLatin1( jReqDoc.toJson() );
    qDebug() << "Request:n" << qPrintable( jReqStr );
    // Response: Read JSON document and inspect its elements
    const auto jRspDoc = QJsonDocument::fromJson( jReqStr.toLatin1() );
    const auto jRspObj = jRspDoc.object();
    const auto jRspArr = jRspObj[ jArrKey ].toArray();
    const auto jRspTst = jRspObj[ jTstKey ].toObject();
    qDebug() << "Response:" << jRspArr;
    qDebug() << "Test Obj:" << jRspTst;
    qDebug() << ">> Hello:" << jRspTst.value( "Hello" ).toString();
    return 0;
}

输出:

Request:
 {
    "levan": [
        {
            "id": 1
        },
        {
            "cb": 0
        },
        {
            "cc": 0
        }
    ],
    "test": {
        "Hello": "World"
    }
}
Response: QJsonArray([{"id":1},{"cb":0},{"cc":0}])
Test Obj: QJsonObject({"Hello":"World"})
>> Hello: "World"

你把一个数组作为文档根目录,所以先检索它:

QJsonDocument jsonResponse = QJsonDocument::fromJson(str.toLatin1());
QJsonArray jsonArray = jsonResponse.array();

检查它是否为空,如果没有,则获取第一项(levan 对象(:

if(!jsonArray.isEmpty())
{
    QJsonObject jsonObject = jsonArray.first().toObject();

您现在可以读取对象键,例如:

    qDebug()<< jsonObject.value("tipo");

将打印:

QJsonValue(string, "reforço"(

请注意,levan 不是键,而是变量名。所以这行:

jsonResponse.object().value("levan");

永远行不通。

如果问题仍然存在,下面是调试代码的一些提示。

首先,检查解析错误,方式如下:

QJsonParseError parseError;
QJsonDocument jsonResponse = QJsonDocument::fromJson(str.toLatin1(), &parseError);
if(parseError.error != QJsonParseError::NoError)
{
    qDebug() << "Parse error: " << parseError.errorString();
}

如果发生,只需检查字符串(最好:无论如何都要检查它(,看看有什么:

qDebug() << str.toLatin1().data();

预期输出为:

[
    {
        "ca": 10,
        "cb": 0,
        "cc": 0,
        "cd": 0,
        "ce": 0,
        "cf": 0,
        "cg": 0,
        "ch": 0,
        "id": 1,
        "tipo": "reforço"
    }
]