前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Qt开源网络库[8]-上传文件与超时处理

Qt开源网络库[8]-上传文件与超时处理

作者头像
Qt君
发布2023-03-17 15:12:48
1.4K0
发布2023-03-17 15:12:48
举报
文章被收录于专栏:跟Qt君学编程跟Qt君学编程

重构了部分代码并在此基础上添加"上传文件"和"超时处理"的功能

一个简单的使用例子:

代码语言:javascript
复制
HttpClient client;
client.get("https://qthub.com")
      .onSuccess([](QString result) { qDebug()<<"result:"<<result; })
      .onFailed([](QString err) { qDebug()<<"error:"<<err; })
      .exec();

1. 如何使用?

  • 采用head-only的方式实现。只需在你的工程中包含 src 目录的 HttpClient.hpp 文件即可。
  • 源码地址在文末。

2. 使用文档

2.1 使用信号槽的方式实现成功与失败的事件处理

接口:

  • Http请求返回成功的信号槽绑定
代码语言:javascript
复制
HttpRequest &onSuccess(const QObject *receiver, const char *method);
HttpRequest &onSuccess(std::function<void (QNetworkReply*)> lambda);
HttpRequest &onSuccess(std::function<void (QVariantMap)> lambda);
HttpRequest &onSuccess(std::function<void (QByteArray)> lambda);
  • Http请求返回失败的信号槽绑定
代码语言:javascript
复制
HttpRequest &onFailed(const QObject *receiver, const char *method);
HttpRequest &onFailed(std::function<void (QString)> lambda);
HttpRequest &onFailed(std::function<void (QNetworkReply::NetworkError)> lambda);
HttpRequest &onFailed(std::function<void (QNetworkReply*)> lambda);

例子:

代码语言:javascript
复制
static HttpClient client;
client.get("https://qthub.com")
      .onSuccess(this, SLOT(onSuccess(QString)))
      .onFailed(this, SLOT(onFailed(QString)))
      .exec(); // 执行Http操作

2.2 使用匿名函数的方式实现成功与失败的事件处理

接口:

  • Http请求返回成功的回调事件
代码语言:javascript
复制
HttpRequest &onSuccess(std::function<void (QNetworkReply*)> lambda);
HttpRequest &onSuccess(std::function<void (QVariantMap)> lambda);
HttpRequest &onSuccess(std::function<void (QByteArray)> lambda);
  • Http请求返回失败的回调事件
代码语言:javascript
复制
HttpRequest &onFailed(std::function<void (QString)> lambda);
HttpRequest &onFailed(std::function<void (QNetworkReply::NetworkError)> lambda);
HttpRequest &onFailed(std::function<void (QNetworkReply*)> lambda);

例子:

代码语言:javascript
复制
client.get("https://qthub.com")
      .onSuccess([](QString result) { qDebug()<<"result:"<<result.left(100); })
      .onFailed([](QString error) { qDebug()<<"error:"<<error; })
      .exec();

2.3 以信号槽的方式获取下载进度

接口:

代码语言:javascript
复制
HttpRequest &onDownloadProgress(const QObject *receiver, const char *method);

例子:

代码语言:javascript
复制
client.get("https://qthub.com")
      .onSuccess(this, SLOT(onSuccess(QString)))
      .onDownloadProgress(this, SLOT(onDownloadProgress(qint64, qint64)))
      .onFailed(this, SLOT(onFailed(QString)))
      .exec();

2.4 以匿名函数的方式获取下载进度

接口:

代码语言:javascript
复制
HttpRequest &onDownloadProgress(std::function<void (qint64, qint64)> lambda);

例子:

代码语言:javascript
复制
client.get("https://qthub.com")
      .onSuccess([](QString result) { qDebug()<<"result: " << result.left(10); })
      .onDownloadProgress([](qint64 bytesReceived, qint64 bytesTotal) {
          qDebug() << "lambda bytes received: " << bytesReceived
                   << "bytes total: " << bytesTotal;
       })
      .onFailed([](QString error) { qDebug()<<"error: " << error; })
      .exec();

2.5 post 上传文件并获取上传进度

接口:

代码语言:javascript
复制
HttpRequest &onUploadProgress(const QObject *receiver, const char *method);
HttpRequest &onUploadProgress(std::function<void (qint64, qint64)> lambda);

例子:

代码语言:javascript
复制
client.post("http://httpbin.org/post")
      .bodyWithFile("text_file", "helloworld.txt")
      .onUploadProgress([](qint64 bytesSent, qint64 bytesTotal) {
          qDebug() << "lambda bytes sent: " << bytesSent
                   << "bytes total: " << bytesTotal;
       })
      .onSuccess([](QString result) { qDebug()<<"result: " << result.left(100); })
      .onFailed([](QString error) { qDebug()<<"error: " << error; })
      .exec();

2.6 自定义超时时间和超时处理

  • timeout(ms)是设置超时时间,单位为毫秒(ms)。
  • onTimeout 为超时回调,当超时事件触发,自动调用 onTimeout 回调。

接口:

  • 设置超时时间
代码语言:javascript
复制
HttpRequest &timeout(const int &msec = -1);
  • 设置超时的回调函数
代码语言:javascript
复制
HttpRequest &onTimeout(const QObject *receiver, const char *method);
HttpRequest &onTimeout(std::function<void (QNetworkReply*)> lambda);
HttpRequest &onTimeout(std::function<void ()> lambda);

例子:

代码语言:javascript
复制
client.get("https://qthub.com")
      .onSuccess([](QString result) { qDebug()<<"result:"<<result.left(100); })
      .onFailed([](QString error) { qDebug()<<"error:"<<error; })
      .onTimeout([](QNetworkReply *) { qDebug()<<"timeout"; }) // 超时处理
      .timeout(1000) // 1s超时
      .exec();

2.7 由于 HttpClient 是异步实现,我们需要同步时可以这样做

接口:

代码语言:javascript
复制
HttpRequest &block();

例子:

代码语言:javascript
复制
client.get("https://qthub.com")
      .onSuccess(this, SLOT(onSuccess(QString)))
      .onFailed(this, SLOT(onFailed(QString)))
      .block() // 阻塞同步操作
      .exec(); // 执行Http操作

2.8 添加 header

接口:

代码语言:javascript
复制
HttpRequest &header(const QString &key, const QVariant &value);
HttpRequest &headers(const QMap<QString, QVariant> &headers);

例子:

代码语言:javascript
复制
client.post("https://example.com")
      .header("content-type", "application/json")
      .queryParam("key", "Hello world!")
      .body(R"({"user": "test"})")
      .onSuccess([](QString result){})
      .onFailed([](QString error){})
      .exec();

添加 params

接口:

代码语言:javascript
复制
HttpRequest &queryParam(const QString &key, const QVariant &value);
HttpRequest &queryParams(const QMap<QString, QVariant> &params);

例子:

代码语言:javascript
复制
client.get("https://example.com")
      .queryParam("key1", "value1")
      .queryParam("key2", "value2")
      .queryParam("key3", "value3")
      .onSuccess([](QString result){})
      .onFailed([](QString error){})
      .exec();

上面代码等同于:

代码语言:javascript
复制
client.get("https://example.com?key1=value1&key2=value2&key3=value3")
      .onSuccess([](QString result){})
      .onFailed([](QString error){})

2.9 添加 body

接口:

  • 原始数据
代码语言:javascript
复制
HttpRequest &body(const QByteArray &raw);
HttpRequest &bodyWithRaw(const QByteArray &raw);
  • json 数据
代码语言:javascript
复制
HttpRequest &body(const QJsonObject &json);
HttpRequest &bodyWithJson(const QJsonObject &json);
  • 表单数据
代码语言:javascript
复制
HttpRequest &body(const QVariantMap &formUrlencodedMap);
HttpRequest &bodyWithFormUrlencoded(const QVariantMap &keyValueMap);
  • 混合消息
代码语言:javascript
复制
HttpRequest &body(QHttpMultiPart *multiPart);
HttpRequest &bodyWithMultiPart(QHttpMultiPart *multiPart);
  • 文件消息
代码语言:javascript
复制
HttpRequest &body(const QString &key, const QString &file);
HttpRequest &bodyWithFile(const QString &key, const QString &file);
HttpRequest &bodyWithFile(const QMap<QString/*key*/, QString/*file*/> &fileMap);

例子:

发送原始数据
代码语言:javascript
复制
client.post("http://httpbin.org/post")
      .body("hello world")
      .onSuccess([](QString result){qDebug()<<result;})
      .onFailed([](QString error){qDebug()<<error;})
      .exec();
发送 json 数据
代码语言:javascript
复制
QJsonObject json
{
    {"property1", 1},
    {"property2", 2}
};

client.post("http://httpbin.org/post")
      .body(json)
      .onSuccess([](QString result){qDebug()<<result;})
      .onFailed([](QString error){qDebug()<<error;})
      .exec();
发送表单数据
代码语言:javascript
复制
QVariantMap map
{
    {"property1", 1},
    {"property2", 2}
};

client.post("http://httpbin.org/post")
      .body(map)
      .onSuccess([](QString result){qDebug()<<result;})
      .onFailed([](QString error){qDebug()<<error;})
      .exec();
发送混合消息
代码语言:javascript
复制
    QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);

    QFile *file = new QFile("demo.txt");
    file->open(QIODevice::ReadOnly);
    file->setParent(multiPart);

    QString dispositionHeader = QString("form-data; name=\"%1\";filename=\"%2\"")
            .arg("text_file")
            .arg(file->fileName());

    QHttpPart part;
    part.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("text/plain"));
    part.setHeader(QNetworkRequest::ContentDispositionHeader, dispositionHeader);
    part.setBodyDevice(file);

    multiPart->append(part);

    QString contentType = QString("multipart/form-data;boundary=%1").arg(multiPart->boundary().data());

HttpClient client;
client.post("http://httpbin.org/post")
      .header("content-type", contentType)
      .body(multiPart)
      .onSuccess([](QString result){ qDebug()<<result.left(1000); })
      .onFailed([](QString error){ qDebug()<<error; })
      .exec();
发送文件
代码语言:javascript
复制
HttpClient client;
client.post("http://httpbin.org/post")
      .body("text_file", "demo.txt")
      .body("image_file", "demo.jpg")
      .onSuccess([](QString result){ qDebug()<<result.left(1000); })
      .onFailed([](QString error){ qDebug()<<error; })
      .exec();

2.10 携带特定的用户数据到响应回调函数

接口:

代码语言:javascript
复制
HttpRequest &userAttribute(const QVariant &value);

例子:

代码语言:javascript
复制
client.get("http://httpbin.org/get")
      .userAttribute("Hello world!")
      .onSuccess([](QNetworkReply *reply) {
            QVariant value = reply->request().attribute(QNetworkRequest::User);
            qDebug()<< value.toString();
       })
      .onFailed([](QString error){ qDebug()<<error; })
      .exec();

3. 源码地址

访问 https://github.com/aeagean/QtNetworkService

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-05-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Qt君 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 如何使用?
  • 2. 使用文档
    • 2.1 使用信号槽的方式实现成功与失败的事件处理
      • 接口:
      • 例子:
    • 2.2 使用匿名函数的方式实现成功与失败的事件处理
      • 接口:
      • 例子:
    • 2.3 以信号槽的方式获取下载进度
      • 接口:
      • 例子:
    • 2.4 以匿名函数的方式获取下载进度
      • 接口:
      • 例子:
    • 2.5 post 上传文件并获取上传进度
      • 接口:
      • 例子:
    • 2.6 自定义超时时间和超时处理
      • 接口:
      • 例子:
    • 2.7 由于 HttpClient 是异步实现,我们需要同步时可以这样做
      • 接口:
      • 例子:
    • 2.8 添加 header
      • 接口:
      • 例子:
    • 添加 params
      • 接口:
      • 例子:
    • 2.9 添加 body
      • 接口:
      • 例子:
    • 2.10 携带特定的用户数据到响应回调函数
      • 接口:
      • 例子:
  • 3. 源码地址
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档