在Qt5中使用Http Rest客户端请求并解析Json数据
在现代软件开发中,HTTP REST客户端请求是与服务器通信的重要方式之一。在Qt5中,我们可以使用QNetworkAccessManager
类来执行HTTP请求,并使用QSerializer库来解析JSON数据。本文将详细说明如何使用这些工具,并提供GET、POST、PUT、DELETE等请求的示例。
1. 准备工作
首先,我们需要包括必要的头文件,并确保我们的类继承了QObject
。
#include <QNetworkAccessManager> #include <QNetworkReply> #include <QNetworkRequest> #include <QUrlQuery> #include <QEventLoop> #include "ReplyData.h"
2. 创建HttpClient类
我们将创建一个HttpClient
类来处理HTTP请求。这个类将包含一个用于发送GET请求的方法。
class HttpClient : public QObject { Q_OBJECT public: HttpClient(QObject* parent = nullptr) : QObject(parent) { } public: ReplyData Get(const QString& url) { QNetworkAccessManager manager; QNetworkRequest request(url); request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/json;charset=utf-8;"); QNetworkReply* reply = manager.get(request); QEventLoop eloop; QObject::connect(reply, &QNetworkReply::finished, &eloop, &QEventLoop::quit); QObject::connect(reply, &QNetworkReply::errorOccurred, &eloop, &QEventLoop::quit); eloop.exec(); ReplyData data; if (reply->error() != QNetworkReply::NoError) { auto errorString = reply->errorString(); data.code = -2; data.message = errorString; reply->deleteLater(); return data; } auto jsonStr = reply->readAll(); reply->deleteLater(); if (jsonStr.size() == 0) return data; data.fromJson(jsonStr); return data; } ReplyData Get(const QUrl& url) { QNetworkAccessManager manager; QNetworkRequest request(url); request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/json;charset=utf-8;"); QNetworkReply* reply = manager.get(request); QEventLoop eloop; QObject::connect(reply, &QNetworkReply::finished, &eloop, &QEventLoop::quit); QObject::connect(reply, &QNetworkReply::errorOccurred, &eloop, &QEventLoop::quit); eloop.exec(); ReplyData data; if (reply->error() != QNetworkReply::NoError) { auto errorString = reply->errorString(); data.code = -2; data.message = errorString; reply->deleteLater(); return data; } auto jsonStr = reply->readAll(); reply->deleteLater(); if (jsonStr.size() == 0) return data; data.fromJson(jsonStr); return data; } ReplyData Post(const QString& url, const QByteArray& jsonObj) { QNetworkAccessManager manager; QNetworkRequest request(url); request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/json;charset=utf-8;"); QNetworkReply* reply = manager.post(request, jsonObj); QEventLoop eloop; QObject::connect(reply, &QNetworkReply::finished, &eloop, &QEventLoop::quit); QObject::connect(reply, &QNetworkReply::errorOccurred, &eloop, &QEventLoop::quit); eloop.exec(); ReplyData data; if (reply->error() != QNetworkReply::NoError) { data.code = -2; data.message = reply->errorString(); reply->deleteLater(); return data; } auto jsonStr = reply->readAll(); reply->deleteLater(); if (!jsonStr.isEmpty()) { data.fromJson(jsonStr); } return data; } ReplyData Post(const QUrl& url, const QByteArray& jsonObj) { QNetworkAccessManager manager; QNetworkRequest request(url); request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/json;charset=utf-8;"); QNetworkReply* reply = manager.post(request, jsonObj); QEventLoop eloop; QObject::connect(reply, &QNetworkReply::finished, &eloop, &QEventLoop::quit); QObject::connect(reply, &QNetworkReply::errorOccurred, &eloop, &QEventLoop::quit); eloop.exec(); ReplyData data; if (reply->error() != QNetworkReply::NoError) { data.code = -2; data.message = reply->errorString(); reply->deleteLater(); return data; } auto jsonStr = reply->readAll(); reply->deleteLater(); if (!jsonStr.isEmpty()) { data.fromJson(jsonStr); } return data; } ReplyData Put(const QString& url, const QByteArray& jsonObj) { QNetworkAccessManager manager; QNetworkRequest request(url); request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/json;charset=utf-8;"); QNetworkReply* reply = manager.put(request, jsonObj); QEventLoop eloop; QObject::connect(reply, &QNetworkReply::finished, &eloop, &QEventLoop::quit); QObject::connect(reply, &QNetworkReply::errorOccurred, &eloop, &QEventLoop::quit); eloop.exec(); ReplyData data; if (reply->error() != QNetworkReply::NoError) { data.code = -2; data.message = reply->errorString(); reply->deleteLater(); return data; } auto jsonStr = reply->readAll(); reply->deleteLater(); if (!jsonStr.isEmpty()) { data.fromJson(jsonStr); } return data; } ReplyData Put(const QUrl& url, const QByteArray& jsonObj) { QNetworkAccessManager manager; QNetworkRequest request(url); request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/json;charset=utf-8;"); QNetworkReply* reply = manager.put(request, jsonObj); QEventLoop eloop; QObject::connect(reply, &QNetworkReply::finished, &eloop, &QEventLoop::quit); QObject::connect(reply, &QNetworkReply::errorOccurred, &eloop, &QEventLoop::quit); eloop.exec(); ReplyData data; if (reply->error() != QNetworkReply::NoError) { data.code = -2; data.message = reply->errorString(); reply->deleteLater(); return data; } auto jsonStr = reply->readAll(); reply->deleteLater(); if (!jsonStr.isEmpty()) { data.fromJson(jsonStr); } return data; } ReplyData Delete(const QString& url) { QNetworkAccessManager manager; QNetworkRequest request(url); request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/json;charset=utf-8;"); QNetworkReply* reply = manager.deleteResource(request); QEventLoop eloop; QObject::connect(reply, &QNetworkReply::finished, &eloop, &QEventLoop::quit); QObject::connect(reply, &QNetworkReply::errorOccurred, &eloop, &QEventLoop::quit); eloop.exec(); ReplyData data; if (reply->error() != QNetworkReply::NoError) { data.code = -2; data.message = reply->errorString(); reply->deleteLater(); return data; } auto jsonStr = reply->readAll(); reply->deleteLater(); if (!jsonStr.isEmpty()) { data.fromJson(jsonStr); } return data; } ReplyData Delete(const QUrl& url) { QNetworkAccessManager manager; QNetworkRequest request(url); request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/json;charset=utf-8;"); QNetworkReply* reply = manager.deleteResource(request); QEventLoop eloop; QObject::connect(reply, &QNetworkReply::finished, &eloop, &QEventLoop::quit); QObject::connect(reply, &QNetworkReply::errorOccurred, &eloop, &QEventLoop::quit); eloop.exec(); ReplyData data; if (reply->error() != QNetworkReply::NoError) { data.code = -2; data.message = reply->errorString(); reply->deleteLater(); return data; } auto jsonStr = reply->readAll(); reply->deleteLater(); if (!jsonStr.isEmpty()) { data.fromJson(jsonStr); } return data; } QUrl CreateQueryString(const QString& baseUrl, const QMap<QString, QString>& queryParams) { QUrl url(baseUrl); QUrlQuery query; //for (auto it = queryParams.constBegin(); it != queryParams.constEnd(); ++it) query.addQueryItem(it.key(), it.value()); for (const auto& key: queryParams.keys()) query.addQueryItem(key, queryParams.value(key)); url.setQuery(query); return url; } }; Q_GLOBAL_STATIC(HttpClient, httpClient)
3. 定义数据模型类
我们使用QSerializer库来定义数据模型类,这些类将帮助我们解析和序列化JSON数据。以下是示例类:ReplyData
作为通用返回和模型类ShiftAnalyze
、CNCPosition
、PullMulti
。
#ifndef REPLY_DATA_H #define REPLY_DATA_H #include "qserializer.h" class ReplyData : public QSerializer { Q_GADGET QS_SERIALIZABLE public: ReplyData() = default; QS_FIELD(int, code) QS_FIELD(QString, message) QS_FIELD(QJsonValue, data) }; #endif #ifndef SHIFT_ANALYZE_H #define SHIFT_ANALYZE_H #include "qserializer.h" class ShiftAnalyze : public QSerializer { Q_GADGET QS_SERIALIZABLE public: ShiftAnalyze() = default; QS_FIELD(QString, shiftType) QS_FIELD(float, totalPrintTime) QS_FIELD(float, totalPrintWeight) QS_FIELD(float, totalTemperatureTime) QS_FIELD(float, totalIdleTime) QS_FIELD(float, totalBackhaulTime) QS_FIELD(float, totalArcSeekingTime) }; #endif #ifndef CNC_POSITION_H #define CNC_POSITION_H #include "qserializer.h" class CNCPosition : public QSerializer { Q_GADGET QS_SERIALIZABLE public: CNCPosition() = default; QS_COLLECTION(QVector, QString, axis) QS_COLLECTION(QVector, QString, units) QS_COLLECTION(QVector, float, absoluteCoords) QS_COLLECTION(QVector, float, relativeCoords) QS_COLLECTION(QVector, float, machineCoords) QS_COLLECTION(QVector, float, distances) }; #endif #pragma once #include "qserializer.h" class PullMulti : public QSerializer { Q_GADGET QS_SERIALIZABLE public: QS_FIELD(QStringList, fCodes) };
4. 处理HTTP响应
在主函数中,我们创建HttpClient
对象并发送GET请求。然后,我们使用QSerializer将返回的JSON数据解析为ShiftAnalyze
对象。
int main(int argc, char* argv[]) { QCoreApplication a(argc, argv); Person toWrite; toWrite.age = 25; toWrite.weight = 74.6; toWrite.name = "linxmouse"; toWrite.fixedAddr = Address("jiangxia", "wuhan"); toWrite.languages = QStringList() << "c" << "c++" << "c#"; toWrite.scores = QVariantList() << 8 << 8 << 9; toWrite.addresses = QVector<Address>() << Address("js", "jm") << Address("py", "gz"); qDebug() << toWrite.toRawJson().constData(); QFile write2Json("person.json"); if (write2Json.exists()) write2Json.remove(); if (write2Json.open(QIODevice::WriteOnly)) { write2Json.write(toWrite.toRawJson()); write2Json.close(); } QFile read2Object("person.json"); if (read2Object.exists()) { if (read2Object.open(QIODevice::ReadOnly)) { Person fromRead; fromRead.fromJson(read2Object.readAll()); read2Object.close(); } } ReplyData data = httpClient->Get("http://localhost:9001/dps/service/GetPreviousShiftAnalyze"); if (data.code == 0) { ShiftAnalyze shiftAnalyze; shiftAnalyze.fromJson(data.data); } QMap<QString, QString> parmas; parmas["fcode"] = "cnc_position"; QUrl cnc_position = httpClient->CreateQueryString("http://localhost:9001/das/services/Pull", parmas); ReplyData data1 = httpClient->Get(cnc_position); if (data1.code == 0) { CNCPosition cncPosition; cncPosition.fromJson(data1.data); } //PullMulti pullMulti; //pullMulti.fCodes << "arc_voltage" << "rolling_force"; QJsonObject jsonObj; jsonObj.insert("fCodes", QJsonArray() << "arc_voltage" << "rolling_force"); //ReplyData data2 = httpClient->Post("http://localhost:9001/das/services/PullMulti", pullMulti.toRawJson()); ReplyData data2 = httpClient->Post("http://localhost:9001/das/services/PullMulti", QJsonDocument(jsonObj).toJson()); if (data2.code == 0) { auto list = data2.data.toVariant().toStringList(); } return a.exec(); }
通过本文,我们了解了如何在Qt5中使用QNetworkAccessManager
和QSerializer库来处理HTTP REST客户端请求,并解析JSON数据。通过定义数据模型类,我们可以方便地序列化和反序列化JSON数据,从而简化了与服务器的通信。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗