QNetworkAccessManager使用的简单封装

实现对QNetworkAccessManager使用方式的简单封装类:HttpServer

增加:

1. 使用QEventLoop实现同步请求
2. 异步请求可以传一个QVariant参数
3. 可以设置超时时间

限制:

1.只能简单的使用put/post方法
2.post 固定参数 ContentTypeHeader == application/json
3.put 固定参数 ContentTypeHeader == application/x-www-form-urlencoded
4.除上述参数外,其他参数都是默认设置
4.没有考虑https协议

使用方式:

  1. 使用factory函数获取类指针,异步调用可以设置自定义参数,会传给slot函数
  2. 如果异步调用,需连接signal和slot函数,使用setConnectTo可以方便连接参数最多的signal,slot函数
  3. 调用put/post相关函数

例子:
异步:

// 调用
QString url = "http://192.168.1.1:8080/XXX";
QString data = "{}";
QVariant param = 100;
HttpServer *http = HttpServer::factory(this, param);
http->setConnectTo(this);
http->postRequest(url, data);

.................................

// slot函数
void XXX::finished(QNetworkReply *reply, QVariant param, bool timeout)
{
	int myParam = param.toInt();
	int httpCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
	QString json = QTextCodec::codecForName("UTF-8")->toUnicode(reply->readAll());
	reply->deleteLater();
}

同步:

HttpServer *http = HttpServer::factory(this);
bool timeout;
auto *reply = http->postRequestSyn(url, data, &timeout);

if(!timeout) {
	int httpCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
	QString json = QTextCodec::codecForName("UTF-8")->toUnicode(reply->readAll());
}
reply->deleteLater();
http->deleteLater();

头文件:

#ifndef HTTPSERVER_H
#define HTTPSERVER_H

#include <QObject>
#include <QScopedPointer>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QNetworkRequest>
#include <QTimer>

class HttpServer : public QObject
{
    Q_OBJECT
public:
	static HttpServer *factory(QObject *parent = 0, QVariant parameter = QVariant());
	static HttpServer *factory(QVariant parameter = QVariant());

	// 异步 get 请求
	// \param timeout 设置超时,结果作为槽函数实参
    void getRequest(const QString& url, bool timeout = false, long time = WAIT_TIME);

    // 同步 get 请求
	// \param timeout 指针不为0时进行超时设置,并且,接收是否超时结果
    QNetworkReply *getRequestSyn(const QString& url, bool *timeout = 0, long time = WAIT_TIME);

	// 异步 post 请求,data 为 json
	// \param timeout 设置超时,结果作为槽函数实参
	void postRequest(const QString& url, const QString &data, bool timeout = false, long time = WAIT_TIME);

	// 同步 post 请求,data 为 json
	// \param timeout 指针不为0时进行超时设置,并且,接收是否超时结果
	QNetworkReply *postRequestSyn(const QString& url, const QString &data, bool *timeout = 0, long time = WAIT_TIME);

	// 异步请求时设置信号接收对象,三参数信号
	// 也可用QObject::connect自定义接收对象和其他slot函数
	void setConnectTo(QObject *receiver);
    
signals:
	// 可以通过setConnectTo连接
    void finished(QNetworkReply *reply, QVariant param, bool isTimeout);
	// 自己连接
	void finished(QNetworkReply *reply, QVariant param);
	void finished(QNetworkReply *reply, bool isTimeout);
	void finished(QNetworkReply *reply);

private slots:
    void finished();
    void timeOut();

private:
	HttpServer(QObject *parent = 0,  QVariant parameter = QVariant());

    void get(const QString& url);
    void get_timeout(const QString& url, QTimer *timer, long time);
    QNetworkReply *get_syn(const QString& url);
    QNetworkReply *get_syn_timeout(const QString& url, bool *timeout, long time);

	void post(const QString& url, const QString &data);
	void post_timeout(const QString& url, const QString &data, QTimer *timer, long time);
	QNetworkReply *post_syn(const QString& url, const QString &data);
	QNetworkReply *post_syn_timeout(const QString& url, const QString &data, bool *timeout, long time);

    QNetworkRequest get_request(const QString& url);
	QNetworkRequest post_request(const QString& url);
	QByteArray post_data(const QString &data);

	QNetworkReply *HttpServer::syn_timeout(QNetworkReply *reply, bool *isTimeout, long time);
	QNetworkReply *HttpServer::syn(QNetworkReply *reply);

	void emitSignals(QNetworkReply *reply, QVariant param, bool isTimeout);

    QScopedPointer<QNetworkAccessManager> mManager;
    QScopedPointer<QTimer> mTimer;
    QNetworkReply *mReply;
    QVariant mParam;

	enum {
		WAIT_TIME = 10000
	};
};

#endif // HTTPSERVER_H

实现文件:

#include <QEventLoop>
#include <QTextCodec>

#include "httpserver.h"

 HttpServer *HttpServer::factory(QObject *parent,  QVariant parameter)
{
	return new HttpServer(parent, parameter);
}

HttpServer *HttpServer::factory( QVariant parameter)
{
	return new HttpServer(0, parameter);
}

HttpServer::HttpServer(QObject *parent,  QVariant parameter)
    :QObject(parent)
    ,mParam(parameter)
    ,mReply(nullptr)
{
    mManager.reset(new QNetworkAccessManager);
    mTimer.reset(new QTimer);

    connect(mTimer.data(), SIGNAL(timeout()), this, SLOT(timeOut()));
}

void HttpServer::setConnectTo(QObject *receiver)
{
	connect(this, SIGNAL(finished(QNetworkReply *, QVariant, bool)), receiver, SLOT(finished(QNetworkReply *, QVariant, bool)));
}

void HttpServer::getRequest(const QString& url, bool timeout, long time)
{
    if(timeout)
        get_timeout(url, mTimer.data(), time);
    else
        get(url);
}

QNetworkReply *HttpServer::getRequestSyn(const QString& url, bool *timeout, long time)
{
    if(timeout)
        return get_syn_timeout(url, timeout, time);
    else
        return get_syn(url);
}

void HttpServer::postRequest(const QString& url, const QString &data, bool timeout, long time)
{
	if(timeout)
		post_timeout(url, data, mTimer.data(), time);
	else
		post(url, data);
}

QNetworkReply *HttpServer::postRequestSyn(const QString& url, const QString &data, bool *timeout, long time)
{
	if(timeout)
		return post_syn_timeout(url ,data, timeout, time);
	else
		return post_syn(url, data);
}

void HttpServer::finished()
{
    mTimer->stop();

    emitSignals(mReply, mParam, false);

    this->deleteLater();
}

void HttpServer::timeOut()
{
    mTimer->stop();

    emitSignals(mReply, mParam, true);
    disconnect(mReply, SIGNAL(finished()), this, SLOT(finished()));

    this->deleteLater();
}

void HttpServer::get(const QString& url)
{
    mReply = mManager->get(get_request(url));
    connect(mReply, SIGNAL(finished()), this, SLOT(finished()));
}

void HttpServer::get_timeout(const QString& url, QTimer *timer, long time)
{
    get(url);
    timer->start(time);
}

QNetworkReply *HttpServer::get_syn_timeout(const QString& url, bool *isTimeout, long time)
{
	QNetworkReply *reply = mManager->get(get_request(url));
	return syn_timeout(reply, isTimeout, time);
}

QNetworkReply *HttpServer::get_syn(const QString& url)
{
    QNetworkReply *reply = mManager->get(get_request(url));
	return syn(reply);
}

void HttpServer::post(const QString& url, const QString &data)
{
	mReply = mManager->post(post_request(url), post_data(data));
	connect(mReply, SIGNAL(finished()), this, SLOT(finished()));
}

void HttpServer::post_timeout(const QString& url, const QString &data, QTimer *timer, long time)
{
	post(url, data);
	timer->start(time);
}

QNetworkReply *HttpServer::post_syn(const QString& url, const QString &data)
{
	QNetworkReply *reply = mManager->post(post_request(url), post_data(data));
	return syn(reply);
}

QNetworkReply *HttpServer::post_syn_timeout(const QString& url, const QString &data, bool *isTimeout, long time)
{

	QNetworkReply *reply = mManager->post(post_request(url), post_data(data));
	return syn_timeout(reply, isTimeout, time);
}

QNetworkReply *HttpServer::syn(QNetworkReply *reply)
{
	QEventLoop loop;
	connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));

	loop.exec();

	return reply;
}

QNetworkReply *HttpServer::syn_timeout(QNetworkReply *reply, bool *isTimeout, long time)
{
	QEventLoop loop;
	connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));

	QTimer timer;
	timer.setInterval(time);
	timer.setSingleShot(true);
	connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));

	timer.start();
	loop.exec();

	if (timer.isActive()) {
		timer.stop();
		*isTimeout = false;
		return reply;
	} else {
		disconnect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
		*isTimeout = true;
		return reply;
	}
}

QNetworkRequest HttpServer::get_request(const QString& url)
{
    QNetworkRequest request;
    request.setUrl(QUrl(url));
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
    return request;
}

QNetworkRequest HttpServer::post_request(const QString& url)
{
	QNetworkRequest request;
	request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
	request.setUrl(QUrl(url));
	return request;
}

QByteArray HttpServer::post_data(const QString &data)
{
	QByteArray postData;
	postData.append(QTextCodec::codecForName("UTF-8")->fromUnicode(data));
	return postData;
}

void HttpServer::emitSignals(QNetworkReply *reply, QVariant param, bool isTimeout)
{
	emit finished(reply, param, isTimeout);
	emit finished(reply, param);
	emit finished(reply, isTimeout);
	emit finished(reply);
}

posted @ 2017-06-29 16:39  Droplet  阅读(1158)  评论(0编辑  收藏  举报