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);
備註:實戰示例,解疑答惑。
--不間端地思考,實時地批判你的工作!