Search code examples
jsonqtpostcontent-typeqnetworkaccessmanager

How to send a POST request in Qt with the JSON body


I'm trying to send a POST request from Qt where the body is in JSON format. Firstly I'm asserting that the request works in curl:

curl -i -H "Content-Type: application/json" -d '{"key1": "value1", "key2": "value2"}' -X POST http://myserver.com/api

That works OK, I'm receiving back the expected response from the server. The same works in Python. Now I need to send this request from C++/Qt:

QNetworkAccessManager *mgr = new QNetworkAccessManager(this);
QHttpMultiPart *httpMultiPart = new QHttpMultiPart(mgr);
QHttpPart *httpPart = new QHttpPart();
httpPart->setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));
httpPart->setBody("{\"key1\":\"value1\", \"key2\":\"value2\"}");

httpMultiPart->append(*httpPart);

QNetworkReply *reply = mgr->post(QNetworkRequest(QUrl("http://myserver.com/api")), httpMultiPart);
QObject::connect(reply, &QNetworkReply::finished, [=]()
        {
            QString err = reply->errorString();
            QString contents = QString::fromUtf8(reply->readAll());
        });

Now I'm getting an error where the errorString returns: `

"Error downloading http://myserver.com/api - server replied: Unsupported Media Type"`

What can be the reason? How should I send the POST request like the one that I'm sending with curl?


Solution

  • QHttpMultiPart is used to send MIME multipart message but in this case it is not required to send that type of information. Instead, you should use QJsonDocument to create the json and convert it to QByteArray:

    QNetworkAccessManager *mgr = new QNetworkAccessManager(this);
    const QUrl url(QStringLiteral("http://myserver.com/api"));
    QNetworkRequest request(url);
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    
    QJsonObject obj;
    obj["key1"] = "value1";
    obj["key2"] = "value2";
    QJsonDocument doc(obj);
    QByteArray data = doc.toJson();
    // or
    // QByteArray data("{\"key1\":\"value1\",\"key2\":\"value2\"}");
    QNetworkReply *reply = mgr->post(request, data);
    
    QObject::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();
    });