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

转载于:https://www.cnblogs.com/kohlrabi/p/7095238.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值