在Qt5中使用Http Rest客戶端請求並解析Json資料

非法关键字發表於2024-06-27

在現代軟體開發中,HTTP REST客戶端請求是與伺服器通訊的重要方式之一。在Qt5中,我們可以使用QNetworkAccessManager類來執行HTTP請求,並使用QSerializer庫來解析JSON資料。本文將詳細說明如何使用這些工具,並提供GET、POST、PUT、DELETE等請求的示例。

1. 準備工作

首先,我們需要包括必要的標頭檔案,並確保我們的類繼承了QObject

#include <QCoreApplication>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QEventLoop>
#include "qserializer.h"
#include "ReplyData.h"
#include "ShiftAnalyze.h"

2. 建立HttpClient類

我們將建立一個HttpClient類來處理HTTP請求。這個類將包含一個用於傳送GET請求的方法。

class HttpClient : public QObject
{
	Q_OBJECT
public:
	HttpClient(QObject* parent = nullptr) : QObject(parent) {}

	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)
		{
			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;
	}
};

3. 定義資料模型類

我們使用QSerializer庫來定義資料模型類,這些類將幫助我們解析和序列化JSON資料。以下是兩個示例類:ReplyDataShiftAnalyze

#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

4. 處理HTTP響應

在主函式中,我們建立HttpClient物件併傳送GET請求。然後,我們使用QSerializer將返回的JSON資料解析為ShiftAnalyze物件。

int main(int argc, char* argv[])
{
	QCoreApplication a(argc, argv);

	HttpClient httpClient;
	ReplyData data = httpClient.Get("http://localhost:9001/dps/service/GetPreviousShiftAnalyze");
	if (data.code == 0)
	{
		ShiftAnalyze shiftAnalyze;
		shiftAnalyze.fromJson(data.data);
	}

	return a.exec();
}

5. 補充其他HTTP方法

為了補全POST、PUT、DELETE等HTTP方法,我們可以在HttpClient類中新增相應的方法。以下是POST方法的示例:

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;
}

類似地,可以新增PUT和DELETE方法。這裡只提供簡要的程式碼片段以作參考:

ReplyData Put(const QString& url, const QByteArray& jsonObj)
{
	// 實現與Post類似,只是使用manager.put()
}

ReplyData Delete(const QString& url)
{
	// 實現與Get類似,只是使用manager.deleteResource()
}

透過本文,我們瞭解瞭如何在Qt5中使用QNetworkAccessManager和QSerializer庫來處理HTTP REST客戶端請求,並解析JSON資料。透過定義資料模型類,我們可以方便地序列化和反序列化JSON資料,從而簡化了與伺服器的通訊。

相關文章