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);
备注:实战示例,解疑答惑。
--不间端地思考,实时地批判你的工作!