实现对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协议
使用方式:
- 使用factory函数获取类指针,异步调用可以设置自定义参数,会传给slot函数
- 如果异步调用,需连接signal和slot函数,使用setConnectTo可以方便连接参数最多的signal,slot函数
- 调用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);
}