QT實戰1:QT5.12 API接口開發HTTP POST(JSON格式)實戰代碼及問題解決

QT實戰:QT5.12 API接口開發HTTP POST(JSON格式)

                                                                  實戰代碼及問題解決

 

在使用QT通過HTTP與服務器交互時,有時得模擬瀏覽器進行提交數據,提交的方式有多種,如:raw 與 form-data等,而這兩者都屬於body字段當中的一種數據形式,此外body中還有x-www-form-urlencoded、binary和GraphQL。

  • raw 可以上次任何格式的文件,如:text、json、xml、html等,本文的例子就是使用raw POST JSON數據;
  • form-data主要是表單數據,鍵值對。這裏鍵值對數據不拼湊在API之後。也有寫成multipart/form-data,它可以包含文件和鍵值對,當上傳的字段是文件時,要用Content-Type來說明文件的類型。
  • x-www-form-urlencoded類似於form-data,數據也是以鍵值對形式存在,但不同的是,它是將數據直接拼湊在API之後,

本文以raw方式提交JSON數據爲例

PRO文件中加

QT       +=  network

不然會提示undefined reference to `_imp___ZN21QNetworkAccessManagerC1EP7QObject

 

#include "QtNetwork/QNetworkAccessManager"

#include "QUrl"

#include "QtNetwork/QHttpMultiPart"

#include "QtNetwork/QNetworkRequest"

#include <QtNetwork/QNetworkReply>

 

#include <QJsonArray>

#include <QJsonObject>

#include <QJsonDocument>

 

POST以JSON數據發送和接收的完整代碼如下:

QJsonArray jsonArray { 1, 2, 3 };
QJsonObject jsonObject;

jsonObject["username"] = "test";
jsonObject["password"] = "123";
jsonObject["array"] = jsonArray;



    QNetworkAccessManager manager;
    
    QNetworkRequest request(QUrl("https://192.168.0.1:8090/user/list"));

    request.setRawHeader("Content-Type", "application/json");

    QSslConfiguration config = QSslConfiguration::defaultConfiguration();
    config.setProtocol(QSsl::TlsV1_0); 
    config.setPeerVerifyMode(QSslSocket::VerifyNone);
    request.setSslConfiguration(config);

    
    QNetworkReply* reply = manager.post(request,QJsonDocument(jsonObject).toJson());

    QEventLoop eventLoop;
    QObject::connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
    eventLoop.exec(); // 進入等待返回,但ui事件循環依然進行。

    if (reply->error() == QNetworkReply::NoError)
    {
        qDebug() << "request protobufHttp NoError";
    }
    else
    {
        qDebug()<<"request protobufHttp handle errors here";
        QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
        //statusCodeV是HTTP服務器的相應碼,reply->error()是Qt定義的錯誤碼,可以參考QT的文檔
        qDebug( "request protobufHttp found error ....code: %d %d\n", statusCodeV.toInt(), (int)reply->error());
        qDebug(qPrintable(reply->errorString()));
    }
    QByteArray result = reply->readAll();
    //qDebug()<<result;

    //解析JSON
    QJsonParseError jsonError;
    QJsonDocument jsonDoc = QJsonDocument::fromJson(result, &jsonError);
    if (jsonError.error != QJsonParseError::NoError) {
        qDebug()<<"Json文件解析錯誤。";
        //return false;
    }

    if (jsonDoc.isObject()) {
        QJsonObject jsonObject = jsonDoc.object();
        qDebug()<<jsonObject;
    }
    else if (jsonDoc.isArray()) {
        QJsonArray jsonArray = jsonDoc.array();
        qDebug()<<jsonArray;
    }
    else {
        qDebug()<<"Json文件解析爲空。";
    }

運行問題及解決

1、HTTPS請求 TLS initialization failed

     解決方法:

    首先需要找到缺失文件 libeay32.dll ssleay32.dll,在Qt安裝目錄下有個Tools文件夾,能找到這兩個文件,具體路徑:
   C:\Qt\Qt5.11.1\Tools\mingw530_32\opt\bin
    將文件複製到應用程序同級目錄就可以了。

 

2、運行後提示錯誤代碼6 :QNetworkReply::SslHandshakeFailedErrorSSL 錯誤

     解決方法:

將QSslConfiguration中的peer verify mode設置爲QSslSocket::VerfifyNone後問題解決。缺省mode爲AutoVerifyPeer。

示例代碼:

 QSslConfiguration config = QSslConfiguration::defaultConfiguration();
        config.setProtocol(QSsl::TlsV1);
        config.setPeerVerifyMode(QSslSocket::VerifyNone);
        request.setSslConfiguration(config);


備註:實戰示例,解疑答惑。

           --不間端地思考,實時地批判你的工作!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章