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

10,032

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();
});
Share:
10,032

Related videos on Youtube

Dmitry Kuzminov
Author by

Dmitry Kuzminov

Updated on June 04, 2022

Comments

  • Dmitry Kuzminov
    Dmitry Kuzminov about 2 years

    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?

  • Dmitry Kuzminov
    Dmitry Kuzminov over 4 years
    That worked, thank you. The follow up question: is there a way to get a string presentation of the request that is about to be sent? That would help to solve the issues like the one I posted here.
  • eyllanesc
    eyllanesc over 4 years
    @DmitryKuzminov Do you mean the raw data that is sent to the server? In general if you want to analyze that type of data then you should use tools like wireshark
  • Dmitry Kuzminov
    Dmitry Kuzminov over 4 years
    The wireshark would be an overkill. In theory if QNetworkRequest internally constructs a string to be used as an HTTP request, there may be a way to view that string directly.
  • eyllanesc
    eyllanesc over 4 years
    @DmitryKuzminov No, your theory is incorrect: QNetworkRequest does not build anything, but only stores information such as headers and url, and it builds the HTTP request is QNetworkAccessManager (in the private API).
  • Arsenic
    Arsenic over 3 years
    your answer may solve the problem, but it would be better if you provide some explanation along with it.