Qt之http客户端类
一、HTTP客户端类功能:
1、POST请求发送:
- 支持发送JSON格式的数据
- 自动处理请求头设置
- 提供上传进度监控、
2、GET请求发送:
- 简单的GET请求实现
- 支持下载进度监控
3、状态监控:
- 通过信号槽机制监控上传/下载进度
- 错误处理和状态回调
/**
* @file HttpClient.h
* @brief HTTP客户端类,用于处理HTTP请求
* @details 提供异步HTTP请求功能,支持GET和POST方法,包含进度监控和错误处理
*/
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QJsonDocument>
#include <QJsonObject>
#include <QEventLoop>
/**
* @class HttpClient
* @brief HTTP客户端类,继承自QObject
* @details 封装了Qt网络请求功能,提供简单的接口进行HTTP通信
*/
class HttpClient : public QObject
{
Q_OBJECT
public:
/**
* @brief 构造函数
* @param parent 父对象指针,用于Qt对象树管理
*/
explicit HttpClient(QObject *parent = nullptr) : QObject(parent) {
manager = new QNetworkAccessManager(this);
}
/**
* @brief 析构函数
* @details 清理网络管理器资源
*/
~HttpClient() {
if (manager) {
manager->deleteLater();
manager = nullptr;
}
}
/**
* @brief 发送POST请求
* @param url 目标URL地址
* @param data 要发送的JSON数据
* @param callback 请求完成后的回调函数,参数为(是否成功, 响应内容/错误信息)
*/
void sendPostRequest(const QString& url, const QJsonObject& data,
std::function<void(bool success, const QString& response)> callback) {
// 创建网络请求对象
QNetworkRequest request(url);
// 设置请求头为JSON格式
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
// 将JSON对象转换为字节数组
QJsonDocument doc(data);
QByteArray postData = doc.toJson();
// 发送POST请求
QNetworkReply* reply = manager->post(request, postData);
// 连接完成信号到响应处理函数
connect(reply, &QNetworkReply::finished, this, [=]() {
handleResponse(reply, callback);
});
// 连接上传进度信号
connect(reply, &QNetworkReply::uploadProgress, this,
&HttpClient::onUploadProgress);
// 连接下载进度信号
connect(reply, &QNetworkReply::downloadProgress, this,
&HttpClient::onDownloadProgress);
}
/**
* @brief 发送GET请求
* @param url 目标URL地址
* @param callback 请求完成后的回调函数,参数为(是否成功, 响应内容/错误信息)
*/
void sendGetRequest(const QString& url,
std::function<void(bool success, const QString& response)> callback) {
QNetworkRequest request(url);
QNetworkReply* reply = manager->get(request);
connect(reply, &QNetworkReply::finished, this, [=]() {
handleResponse(reply, callback);
});
}
signals:
/**
* @brief 上传进度信号
* @param bytesSent 已发送的字节数
* @param bytesTotal 总字节数
*/
void uploadProgressChanged(qint64 bytesSent, qint64 bytesTotal);
/**
* @brief 下载进度信号
* @param bytesReceived 已接收的字节数
* @param bytesTotal 总字节数
*/
void downloadProgressChanged(qint64 bytesReceived, qint64 bytesTotal);
private slots:
/**
* @brief 处理上传进度的槽函数
* @param bytesSent 已发送的字节数
* @param bytesTotal 总字节数
*/
void onUploadProgress(qint64 bytesSent, qint64 bytesTotal) {
emit uploadProgressChanged(bytesSent, bytesTotal);
}
/**
* @brief 处理下载进度的槽函数
* @param bytesReceived 已接收的字节数
* @param bytesTotal 总字节数
*/
void onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) {
emit downloadProgressChanged(bytesReceived, bytesTotal);
}
private:
/** @brief 网络访问管理器指针 */
QNetworkAccessManager* manager;
/**
* @brief 处理网络响应
* @param reply 网络响应对象指针
* @param callback 回调函数
* @details 处理请求完成后的响应数据或错误信息,并调用回调函数
*/
void handleResponse(QNetworkReply* reply,
std::function<void(bool success, const QString& response)> callback) {
if (reply->error() == QNetworkReply::NoError) {
// 请求成功,读取响应数据
QString response = QString::fromUtf8(reply->readAll());
callback(true, response);
} else {
// 请求失败,获取错误信息
QString errorString = reply->errorString();
callback(false, errorString);
}
// 清理响应对象
reply->deleteLater();
}
};
二、使用方式
1、作为类成员变量使用
class MyClass : public QObject {
Q_OBJECT
private:
HttpClient* httpClient;
public:
MyClass(QObject* parent = nullptr) : QObject(parent) {
httpClient = new HttpClient(this); // 将this作为父对象
}
// 不需要显式删除,会随父对象自动删除
~MyClass() {
// httpClient会自动删除,不需要手动删除
}
};
2、 作为局部变量使用
void someFunction() {
// 在栈上创建
HttpClient client;
// 使用client发送请求
client.sendPostRequest("...", data, [](bool success, const QString& response) {
// 处理响应
});
// client会在函数结束时自动销毁
}
3、动态分配使用
void someFunction() {
// 动态创建
HttpClient* client = new HttpClient();
// 使用client发送请求
client->sendPostRequest("...", data, [client](bool success, const QString& response) {
// 处理响应
// 在回调中删除client
client->deleteLater();
});
}
4、使用智能指针
#include <QScopedPointer>
void someFunction() {
QScopedPointer<HttpClient> client(new HttpClient());
// 使用client发送请求
client->sendPostRequest("...", data, [](bool success, const QString& response) {
// 处理响应
});
// client会在QScopedPointer销毁时自动删除
}
三、示例
// 创建客户端实例
HttpClient* client = new HttpClient(this);
// 监听进度信号
connect(client, &HttpClient::uploadProgressChanged, this, [](qint64 sent, qint64 total) {
qDebug() << "Upload progress:" << sent << "/" << total;
});
// 准备POST数据
QJsonObject data;
data["name"] = "test";
data["value"] = 123;
// 发送POST请求
client->sendPostRequest("http://api.example.com/endpoint", data,
[](bool success, const QString& response) {
if (success) {
qDebug() << "Response:" << response;
} else {
qDebug() << "Error:" << response;
}
}
);
注意事项:
- 如果 HttpClient 作为 QObject 的子对象创建,会随父对象自动删除,不需要手动删除
- 使用 deleteLater() 而不是直接 delete,确保在 Qt 事件循环中安全删除对象
- 如果有正在进行的网络请求,建议等待请求完成后再删除 HttpClient
- 使用智能指针可以避免手动管理内存,推荐使用