基于qt的带cookie同步、异步post及get的http请求

本文介绍了一个使用Qt实现的HTTP异步请求管理器,包括GET和POST请求的发送、登录验证处理、同步GET请求及超时管理等功能。通过单例模式确保全局唯一实例,并利用QNetworkAccessManager进行网络交互。
//单例
pragma  once
#include <QMutex>
#include <QScopedPointer>

template <typename T>
class YxSingleton
{
public:
	static T &getInstance();
	YxSingleton(const YxSingleton &other) = default;
	YxSingleton<T> &operator=(const YxSingleton &other) = default;
private:
	static QMutex mutex;
	static QScopedPointer<T> instance;
};

template <typename T> QMutex YxSingleton<T>::mutex;
template <typename T> QScopedPointer<T> YxSingleton<T>::instance;

template<typename T>
T &YxSingleton<T>::getInstance()
{
	if (instance.isNull()) {
		mutex.lock();
		if (instance.isNull()) {
			instance.reset(new T());
		}
		mutex.unlock();
	}
	return *instance.data();
}

#define SINGLETON(Class) \
    private: \
    Class(); \
    ~Class(); \
    Class(const Class &other); \
    Class &operator =(const Class &other); \
    friend class YxSingleton<Class>; \
    friend struct QScopedPointerDeleter<Class>;
#pragma once
#include <QObject>
#include <map>
#include <QNetworkCookie>
#include <QNetworkCookieJar>
#include <QTimer>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QNetworkAccessManager>
#include "YxSingleton.h"

class YxNetworkCookieJar : public QNetworkCookieJar
{
public:
	YxNetworkCookieJar();
	QList<QNetworkCookie> getCookies();
	void setCookies(const QList<QNetworkCookie>& cookieList);
};

class YxReplyTimeout : public QObject
{
	Q_OBJECT
public:
	YxReplyTimeout(QNetworkReply *reply, const int timeout, bool _bansyc) : QObject(reply) {
		Q_ASSERT(reply);
		m_bansyc = _bansyc;
		if (reply && reply->isRunning()) {  // 启动单次定时器
			QTimer::singleShot(timeout, this, SLOT(onTimeout()));
		}
	}
signals:
	void timeout();  // 超时信号 - 供进一步处理
private slots:
	void onTimeout() {  // 处理超时
		QNetworkReply *reply = static_cast<QNetworkReply*>(parent());
		if (reply->isRunning()) {
			reply->abort();
			if (m_bansyc)
			{
				reply->deleteLater();
			}
			emit timeout();
		}
	}
private:
	bool m_bansyc;
};


class YxHttpAsyncRequest :public QObject
{
	SINGLETON(YxHttpAsyncRequest)
	Q_OBJECT
public:
	void RequestGet(QObject*_pObject, const QString&strUrl, std::function<void()> _FinishCallBack, std::function<void()> _timeoutCallBack, int _timeout);
	void RequestLoginPost(QObject*_pObject, std::function<void()> _FinishCallBack, std::function<void()> _timeoutCallBack, int _timeout);
	void RequestPostByCookie(QObject*_pObject, const QString&strUrl, const QString&strParam, std::function<void()> _FinishCallBack, std::function<void()> _timeoutCallBack, int _timeout);
	void SetLoginInfo(QString _strLoginUrl, QString _strLoginParam);
	void SetPlatfromAddr(const QString& _str);
	QString &GetPlatfromAddr();
	void RequestSyncGet(const QString&strUrl, QByteArray&retBuf, std::function<void()> _timeoutCallBack, int _timeout);
private:
	YxNetworkCookieJar m_WorkCookie;
	QString m_strLoginUrl;
	QString m_strLoginParam;
	QNetworkAccessManager m_NetManager;
	QString m_strPlatfromAddr;
};

#include "YxHttpAsyncRequest.h"
#include <QTextCodec>
#include <QEventLoop>

YxNetworkCookieJar::YxNetworkCookieJar()
{

}

QList<QNetworkCookie> YxNetworkCookieJar::getCookies()
{
	return allCookies();
}

void YxNetworkCookieJar::setCookies(const QList<QNetworkCookie>& cookieList)
{
	if (this == NULL) {
		return;
	}
	setAllCookies(cookieList);
}

YxHttpAsyncRequest::YxHttpAsyncRequest(){
	
}
YxHttpAsyncRequest::~YxHttpAsyncRequest(){}
void YxHttpAsyncRequest::RequestGet(QObject*_pObject, const QString&strUrl, std::function<void()> _FinishCallBack, std::function<void()> _timeoutCallBack, int _timeout)
{
	QNetworkRequest request;
	request.setUrl(QUrl(strUrl));
	QNetworkReply *reply = m_NetManager.get(request);

	connect(reply, &QNetworkReply::finished, _pObject, [=]() {
		_FinishCallBack();
	});
	YxReplyTimeout* sptrTimeout = new YxReplyTimeout(reply, _timeout, true);
	// 超时进一步处理
	connect(sptrTimeout, &YxReplyTimeout::timeout, [=]() {
		_timeoutCallBack();
	});
}

void YxHttpAsyncRequest::RequestLoginPost(QObject*_pObject, std::function<void()> _FinishCallBack, std::function<void()> _timeoutCallBack, int _timeout)
{
	QNetworkRequest request;
	request.setUrl(QUrl(m_strLoginUrl));
	request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
	QByteArray encodedString = QTextCodec::codecForName("UTF-8")->fromUnicode(m_strLoginParam);
	QNetworkReply *reply = m_NetManager.post(request, encodedString);
	connect(reply, &QNetworkReply::finished, _pObject, [=]() {
		_FinishCallBack();
	});
	YxReplyTimeout* sptrTimeout = new YxReplyTimeout(reply, _timeout, true);
	// 超时进一步处理
	connect(sptrTimeout, &YxReplyTimeout::timeout, [=]() {
		_timeoutCallBack();
	});
}

void YxHttpAsyncRequest::RequestPostByCookie(QObject*_pObject, const QString&strUrl, const QString&strParam, std::function<void()> _FinishCallBack, std::function<void()> _timeoutCallBack, int _timeout)
{
	QNetworkRequest request;
	request.setUrl(QUrl(strUrl));
	request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
	QByteArray encodedString = QTextCodec::codecForName("UTF-8")->fromUnicode(strParam);
	QNetworkReply *reply = m_NetManager.post(request, encodedString);
	connect(reply, &QNetworkReply::finished, _pObject, [=]() {
		_FinishCallBack();
	});
	YxReplyTimeout* sptrTimeout = new YxReplyTimeout(reply, _timeout, true);
	// 超时进一步处理
	connect(sptrTimeout, &YxReplyTimeout::timeout, [=]() {
		_timeoutCallBack();
	});
}

void YxHttpAsyncRequest::SetLoginInfo(QString _strLoginUrl, QString _strLoginParam)
{
	m_strLoginUrl = _strLoginUrl;
	m_strLoginParam = _strLoginParam;
}

void YxHttpAsyncRequest::SetPlatfromAddr(const QString& _str)
{
	m_strPlatfromAddr = _str;
}

QString & YxHttpAsyncRequest::GetPlatfromAddr()
{
	return m_strPlatfromAddr;
}

void YxHttpAsyncRequest::RequestSyncGet(const QString&strUrl, QByteArray&retBuf, std::function<void()> _timeoutCallBack, int _timeout)
{
	QNetworkRequest request;
	QNetworkAccessManager* pNetManager = new QNetworkAccessManager(this);
	request.setUrl(QUrl(strUrl));
	QNetworkReply *reply = pNetManager->get(request);

	QEventLoop eventLoop;
	connect(pNetManager, SIGNAL(finished(QNetworkReply*)), &eventLoop, SLOT(quit()));
	YxReplyTimeout *pTimeout = new YxReplyTimeout(reply, _timeout, false);
	// 超时进一步处理
	connect(pTimeout, &YxReplyTimeout::timeout, [=]() {
		_timeoutCallBack();
	});
	eventLoop.exec();
	retBuf = reply->readAll();
	delete pTimeout;
	pTimeout = nullptr;
	delete reply;
	reply = nullptr;
	delete pNetManager;
	pNetManager = nullptr;
}

 

评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值