I want to send a put request with JSON body, but with QNetworkAccessManager doesn't have the option to send a request with JSON so I converted it to QByteArray, the structure of the body, when converted to QByteArray, is not a JSON format so that I received an Error with
"Error downloading https://example.api.com/something/DataSet('123456780XYZ') - server replied: Forbidden"
The JSON format I want is like this:
{
"d": {
"Duration": "0.000",
"Id": "123456780XYZ",
"LoadCumulLimit": "0.000",
"Notes": "send from postman in Json format"
}
}
Here is what did I do
QJsonObject data;
data["Duration"] = workplace->data["duration"];
data["Id"] = id;
data["LoadCumulLimit"] = workplace->data["load_cumul_limit"];
data["Notes"] = workplace->dataText["Notes"];
QJsonObject newData;
newData["d"] = data;
QJsonDocument doc(newData);
qDebug() << url;
QByteArray finalData = doc.toJson();
qDebug() << finalData;
reply = manager->put(request, finalData);
connect(reply, &QNetworkReply::finished, [=](){
if(reply->error() == QNetworkReply::NoError){
QString contents = QString::fromUtf8(reply->readAll());
qDebug() << contents;
}
else{
QString err = reply->errorString();
qDebug() << err;
}
reply->deleteLater();
});
But I received the QByteArray like this:
"{\n \"d\": {\n \"Duration\": 8,\n \"IgelId\": \"123456780XYZ\",\n \"LoadCumulLimit\": 25,\n \"Notes\": \"send from IGEL\"\n }\n}\n"
I can send JSON object from client to server but can not get an item from JSON object on the server.
I've tried several examples that I found when I researched I can not solve the problem.
Code to send 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());
Code to receive 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";
}
I can present JSON as text, but I cannot get the items from the JSON.
You're creating a single QJsonObject and then creating a QJsonArray using that object. So, the final output is one JSON object with a nested array with only one object. I'm not sure if you intend to have only one object in array or an array of all those objects.
And, the JSON created in request is not what you're trying to read in response. There's no key levantamento or levan in your request so you cannot find anything against those in response. You need to work on population of objects in request JSON. The below example uses some of your test data for request population and extraction in response. Hope that helps!
Example:
#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;
}
Output:
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"
You put an array as the document root, so retrieve it first:
QJsonDocument jsonResponse = QJsonDocument::fromJson(str.toLatin1());
QJsonArray jsonArray = jsonResponse.array();
Check if it's empty, if not get the first item (the levan object):
if(!jsonArray.isEmpty())
{
QJsonObject jsonObject = jsonArray.first().toObject();
You can now read the object keys, e.g.:
qDebug()<< jsonObject.value("tipo");
will print:
QJsonValue(string, "reforço")
Notice that levan is not a key, but a variable name. So this line:
jsonResponse.object().value("levan");
will never work.
If the issue persists, here's a couple of hints to debug your code.
First, check for parsing errors, this way:
QJsonParseError parseError;
QJsonDocument jsonResponse = QJsonDocument::fromJson(str.toLatin1(), &parseError);
if(parseError.error != QJsonParseError::NoError)
{
qDebug() << "Parse error: " << parseError.errorString();
}
If one occurs, just inspect the string (better: inspect it anyway), to see what came in:
qDebug() << str.toLatin1().data();
The expected output is:
[
{
"ca": 10,
"cb": 0,
"cc": 0,
"cd": 0,
"ce": 0,
"cf": 0,
"cg": 0,
"ch": 0,
"id": 1,
"tipo": "reforço"
}
]
I'm trying to insert an event to google calendar using Qt C++.
Before inserting events, I am able to clear the primary calendar using these lines
const QUrl clearPrimaryUrl("https://www.googleapis.com/calendar/v3/calendars/primary/clear");
void GoogleWrapper::clearPrimaryCalendar()
{
QNetworkReply *reply = google.post(clearPrimaryUrl);
connect(reply, &QNetworkReply::finished, [=]()
{
reply->deleteLater();
if(reply->error() != QNetworkReply::NoError)
{
qCritical() << "Google error:" << reply->errorString();
return;
}
emit primaryCalendarCleared();
});
}
google is an QOAuth2AuthorizationCodeFlow object.
Now to insert events, I use these lines:
const QUrl insertEventUrl("https://www.googleapis.com/calendar/v3/calendars/primary/events");
void GoogleWrapper::insertEvent(const QByteArray &eventData)
{
qDebug() << eventData;
QNetworkReply *reply = google.post(insertEventUrl, eventData);
connect(reply, &QNetworkReply::finished, [=]()
{
reply->deleteLater();
if(reply->error() != QNetworkReply::NoError)
{
qCritical() << "Google error:" << reply->errorString();
return;
}
emit eventInserted();
});
}
But the output I received from qCritical was always Error transferring https://www.googleapis.com/calendar/v3/calendars/primary/events - server replied: Bad Request.
I tried output the eventData to a file and copy paste it to Google's try this API and the below json data works perfectly
{
"description": "some teacher name",
"end": {
"dateTime": "2018-12-19T11:15:00Z"
},
"location": "Room",
"start": {
"dateTime": "2018-12-19T09:30:00Z"
},
"summary": "Subject Name"
}
Anyone have any idea what I did wrong?
The issue is solved thanks to #thuga's comment.
My code was missing the line
google.setContentType(QAbstractOAuth2::ContentType::Json);
I have been trying all day to read data from a json file like below with Qt but can't find a way to do it properly. I tried many things but could not get it right. Can someone help me how to get this correctly?
{
"RawData": {
"Sensors": {
"Channel1" : "10",
"Channel2" : "22",
"Channel3" : "3",
"Channel4" : "48",
"Channel5" : "1",
"Channel6" : "8",
"Channel7" : "16",
"Channel8" : "44"
}
}
}
for now my code looks something like this, though i tried many things with different manners.
QFile jsonCfg("config.json");
if (!jsonCfg.open(QIODevice::ReadOnly)) {
qWarning("Couldn't open json config file.");
return false;
}
QByteArray saveData = jsonCfg.readAll();
QJsonDocument loadDoc(QJsonDocument::fromJson(saveData));
QJsonObject config = loadDoc.object();
QVariantMap root_map = config.toVariantMap();
QVariantMap raw = root_map["RawData"].toMap();
QVariantMap sensor = raw["Sensors"].toMap();
qDebug() << "channel 1" << sensor["Channel1"].toDouble();
you can use QJsonDocument and QJsonObject just like:
QJsonParseError jsonErr;
QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonStr,&jsonErr);
if(jsonErr.error == QJsonParseError::NoError)
{
QJsonObject myJsonObject = jsonDoc.object();
if(myJsonObject["RawData"].isObject())
{
//do somethine your want;
}
}
i want to decode following json with qt:
{
"user": {
"name": "string"
}
}
i'm tried to do it with this code, but does not work:
QJsonDocument jsonResponse = QJsonDocument::fromJson(result.toUtf8());
QJsonObject jsonObject = jsonResponse.object();
QJsonArray jsonArray = jsonObject["user"].toArray();
foreach (const QJsonValue & value, jsonArray)
{
QJsonObject obj = value.toObject();
url = obj["name"].toString();
}
This is the culprit:
QJsonArray jsonArray = jsonObject["user"].toArray();
You are trying to convert the object to an array without any isArray() check. That is, your json does not contain an array therein. Array means [...] in the json world.
You ought to either use toObject() or change your input json.
Without json file change, you would write this:
QJsonDocument jsonResponse = QJsonDocument::fromJson(result.toUtf8());
QJsonObject jsonObject = jsonResponse.object();
QJsonObject userJsonObject = jsonObject.value("user").toObject();
qDebug() << userJsonObject.value("name").toString();