专栏首页跟Qt君学编程Qt开源网络库[2]-接口篇

Qt开源网络库[2]-接口篇

上一篇介绍了Qt开源网络库,有兴趣的可以翻开往期推送.今篇主要介绍该开源网络库接口的用法.

1. 接口目录文件列表:

Network
├── HttpRequest.h
├── HttpResponse.h
└── HttpService.h

2. QtNetworkService网络库接口体现在这三个头文件:

(1)HttpRequest.h是处理网络请求功能,比如参数,body,json数据,表单数据;

(2)HttpResponse.h是处理网络响应功能,当请求数据返回时会经过它处理;

(3)HttpService.h是用户使用的接口层,提供get,post, put, send等http接口.

3. HttpService头文件源代码:

#ifndef HTTP_SERVICE_H
#define HTTP_SERVICE_H

#include "HttpRequest.h"
#include "HttpResponse.h"
#include <QNetworkRequest>
#include <QNetworkReply>

class HttpService : public QNetworkAccessManager
{
    Q_OBJECT
public:
    friend class HttpRequest;

    HttpService();
    ~HttpService();

    HttpRequest get(const QString &url);
    HttpRequest post(const QString &url);
    HttpRequest put(const QString &url);

    HttpRequest send(const QString &url, Operation op = GetOperation);
};

#endif // HTTP_SERVICE_H

HttpService类提供的接口有get, post, put, send这几种方式,url为请求路径,如果使用send方式,则需要指定op的属性,默认为get方式.

4. HttpRequest类头文件源代码:

#ifndef HTTP_REQUEST_H
#define HTTP_REQUEST_H

#include "HttpResponse.h"

#include <QNetworkRequest>
#include <QNetworkAccessManager>
#include <QJsonObject>

#include <functional>

class HttpService;

class HttpRequest
{
public:
    explicit HttpRequest(QNetworkAccessManager::Operation op, HttpService *jsonHttpClient);
    virtual ~HttpRequest();

    HttpRequest &url(const QString &url);
    HttpRequest &header(const QString &key, const QVariant &value);
    HttpRequest &headers(const QMap<QString, QVariant> &headers);

    HttpRequest &queryParam(const QString &key, const QVariant &value);
    HttpRequest &queryParams(const QMap<QString, QVariant> &params);

    /* Mainly used for identification */
    HttpRequest &userAttribute(const QVariant &value);

    HttpRequest &jsonBody(const QVariant &jsonBody);
    /*
     * @onRespone slot support type: void function(QVariantMap resultMap) OR
     *                               void function(QByteArray resultData) OR
     *                               void function(QNetworkReply* reply)
     * note: The same type is only triggered once
     */
    HttpRequest &onResponse(const QObject *receiver, const char *slot, HttpResponse::SupportMethod type = HttpResponse::AutoInfer);

    /*
     * @onError slot support type: void function(QNetworkReply::NetworkErro errorr)
     * note: The same type is only triggered once
     */
    HttpRequest &onError(const QObject *receiver, const char *slot);

    HttpResponse *exec();

private:
    HttpRequest();

private:
    QNetworkRequest m_networkRequest;
    QJsonObject m_jsonBody;
    QNetworkAccessManager::Operation m_op;
    HttpService *m_httpService;
    QMultiMap<QString, QMap<QString, const QObject *>> m_slotsMap;
};

#endif // HTTP_REQUEST_H

HttpRequest类后台逻辑都是封装QNetworkRequest类,提供出来的接口主要有:

(1)url为调用请求路径;

(2)header相当于setRawHeader, 用于设置HTTP头信息;

request.header("Last-Modified", "1994-05-07 08:49:37");

(3)headers用于多个HTTP头信息参数同时写入;

(4)queryParam用于表单提交数据,这个是对于URL的数据拼接,比如:

原url: 
http://www.qt.io
使用queryParam("param1", "test")添加表单数据;
则url变为:
http://www.qt.io?param1=test

(5)queryParams用于多个表单参数同时写入;

(6)userAttribute用于自定义数据,主要配合HttpResponse使用,用于区别请求是哪一个,用得相对较少;

(7)jsonBody用于post,put提交json数据,get无效;

(8)onResponse为设置异步槽函数,当请求回应时,系统自动调用对象接收者(第一个参数)的槽函数(第二个参数).这里底层自动帮你绑定了槽函数.该槽函数需要用户自定义.

<1>该槽函数的定义也是有限制的目前只支持这三种槽函数定义方式:

void function(QVariantMap resultMap) //function为用户定义函数的名字
void function(QByteArray resultData) //function为用户定义函数的名字
void function(QNetworkReply* reply)  //function为用户定义函数的名字

<2>用法:

m_service.get("http:/www.baidu.com")
         .onResponse(this, SLOT(finish(QVariantMap)))
         .onError(this, SLOT(error(QNetworkReply::NetworkError, QNetworkReply*)))
         .exec();

<3>onResponse里面的this为接收者对象,SLOT(finish(QVariantMap))则为该对象的finish槽函数,当请求正常返回时,系统将对自动调用finish槽函数,当然槽函数的QVariantMap则为结果(类型自动转换为QVariantMap),如果返回数据不是json格式,则finish获取到的结果为空.修改为finish(QByteArray)通用做法也可以.最终的处理结果由finish操作.

m_service.get("http:/www.baidu.com")
         .onResponse(this, SLOT(finish(QByteArray)))
         .onError(this, SLOT(error(QNetworkReply::NetworkError, QNetworkReply*)))
         .exec();

<4>onResponse还支持以下类型槽函数

void function(qint64 bytesReceived, qint64 bytesTotal);

该槽函数用于数据接收的进度状态,bytesReceived变量为已经接收到的数据长度,bytesTotal为需要接收的总长度.

示例:

m_service.get("http:/www.baidu.com")
         .onResponse(this, SLOT(downloadProgress(qint64, qint64)))
         .onError(this, SLOT(error(QNetworkReply::NetworkError, QNetworkReply*)))
         .exec();

(9)onError与onResponse用法,但要注意支持的类型不一样

void function(QNetworkReply::NetworkError error);
void function(QString errorString);
void function(QNetworkReply::NetworkError error, QNetworkReply* reply);
void function(QString errorString, QNetworkReply* reply);

(10)exec为执行操作请求,如果没有调用该函数,则请求不会发送.

5. HttpResponse类头文件源代码:

#ifndef HTTP_RESPONSE_H
#define HTTP_RESPONSE_H

#include <QNetworkReply>
#include <QMultiMap>

class HttpResponse : public QNetworkReply
{
    Q_OBJECT
public:
    /*
     * Support Reflex Method
     * default: AutoInfer
     * AutoInfer: Automatic derivation based on type
     */
    enum SupportMethod {
        AutoInfer,
        onResponse_QNetworkReply_A_Pointer,    /* method: void function(QNetworkReply* reply); Is_AutoInfer: true */
        onResponse_QByteArray,                 /* method: void function(QByteArray data); Is_AutoInfer: true */
        onResponse_QVariantMap,                /* method: void function(QVariantMap map); Is_AutoInfer: true */
        onDownloadProgress_qint64_qint64,      /* method: void function(qint64 bytesReceived, qint64 bytesTotal); Is_AutoInfer: true */
        onError_QNetworkReply_To_NetworkError, /* method: void function(QNetworkReply::NetworkError error); Is_AutoInfer: true */
        onError_QString,                       /* method: void function(QString errorString); Is_AutoInfer: true */
        onError_QNetworkReply_To_NetworkError_QNetworkReply_A_Pointer, /* method: void function(QNetworkReply::NetworkError error, QNetworkReply* reply); Is_AutoInfer: true */
        onError_QString_QNetworkReply_A_Poniter/* method: void function(QString errorString), QNetworkReply* reply); Is_AutoInfer: true */
    };

    explicit HttpResponse(QNetworkReply *parent, const QMultiMap<QString, QMap<QString, const QObject *> > &slotsMap);

    virtual ~HttpResponse();

public slots:
    void abort();

private slots:
    void onFinished();
    void onError(QNetworkReply::NetworkError error);
    void onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal);

protected:
    qint64 readData(char *data, qint64 maxlen);

    void slotsMapOperation(QMultiMap<QString, QMap<QString, const QObject *> > &slotsMap);

signals:
    void finished(QNetworkReply *reply);
    void finished(QByteArray data);
    void finished(QVariantMap map);
    void error(QString errorString);
    void error(QNetworkReply::NetworkError error);
    void error(QString errorString, QNetworkReply *reply);
    void error(QNetworkReply::NetworkError error, QNetworkReply *reply);
    void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);

private:
    HttpResponse();

private:
   QMultiMap<QString, QMap<QString, const QObject *> > m_slotsMap;
};


#endif // HTTP_RESPONSE_H

(1) HttpResponse看起来复杂,但实际用户用得不多,主要用于HttpRequest类的使用.用户使用需要关注这个SupportMethod枚举即可

enum SupportMethod {
    AutoInfer,
    onResponse_QNetworkReply_A_Pointer,    /* method: void function(QNetworkReply* reply); Is_AutoInfer: true */
    onResponse_QByteArray,                 /* method: void function(QByteArray data); Is_AutoInfer: true */
    onResponse_QVariantMap,                /* method: void function(QVariantMap map); Is_AutoInfer: true */
    onDownloadProgress_qint64_qint64,      /* method: void function(qint64 bytesReceived, qint64 bytesTotal); Is_AutoInfer: true */
    onError_QNetworkReply_To_NetworkError, /* method: void function(QNetworkReply::NetworkError error); Is_AutoInfer: true */
    onError_QString,                       /* method: void function(QString errorString); Is_AutoInfer: true */
    onError_QNetworkReply_To_NetworkError_QNetworkReply_A_Pointer, /* method: void function(QNetworkReply::NetworkError error, QNetworkReply* reply); Is_AutoInfer: true */
    onError_QString_QNetworkReply_A_Poniter/* method: void function(QString errorString, QNetworkReply* reply); Is_AutoInfer: true */
};

(2)SupportMethod枚举用于HttpRequest类的onResponse的槽函数的参数使用,这里值得注意的是onResponse的最后一个参数type,该作用用于标识槽函数参数的类型是什么,如果Is_AutoInfer: true为真,则第三个参数不需要填写即可自动推导.这里描述得有点抽象但后续文章会重点写到,有兴趣的可以关注一下.

HttpRequest &onResponse(const QObject *receiver, const char *slot, HttpResponse::SupportMethod type)

本文分享自微信公众号 - Qt君(qtjuna),作者:Prosa

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-12-01

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 发布Qt程序打包工具

    Qt君
  • Qt线程使用的两种方法

    一个QThread实例管理程序中的一个线程。QThread的执行开始于run()。默认情况下,run()通过调用exec()启动事件循环,并在线程内运行Qt事件...

    Qt君
  • Qt快捷打包程序方法

    Qt君
  • Linux进程详解

    程序是指储存在外部存储(如硬盘)的一个可执行文件, 而进程是指处于执行期间的程序, 进程包括 代码段(text section) 和 数据段(data sect...

    用户7686797
  • JS打开摄像头并截图上传

    要注意的是,在chrome以外的浏览器中,使用摄像头或多或少会出现一些问题,可能也是老问题了,所以以下代码主要基于chrome使用

    书童小二
  • 进程的描述和创建

    进程在内核态运行时需要自己的堆栈信息,linux内核为每个进程都提供了一个内核栈。对每个进程,Linux内核都把两个不同的数据结构紧凑的存放在一个单独为进程分配...

    De4dCr0w
  • 2.5.1 进程与程序的区别和联系

    (1)进程是程序及其数据在计算机上的一次运行活动,是一个动态的概念。进程的运行实体是程序,离开程序的进程没有存在的意义。从静态角度看,进程是由程序,数据和进程控...

    week
  • Celery 3 版本 定时执行与 异

    Celery 是一个 基于python开发的分布式异步消息任务队列,通过它可以轻松的实现任务的异步处理, 如果你的业务场景中需要用到异步任务,就可以考虑使用ce...

    py3study
  • [jQuery笔记] 简单商品计算统计

    行 者
  • Wijmo 更优美的jQuery UI部件集:在安全站点使用Wijmo控件

    通常我们总会遇到这样的问题,在安全站点(HTTPS)中使用C1Wijmo控件时,用户可能会收到脚本错误。 发生这种状况的是由于我们的CDN链接不是https链接...

    葡萄城控件

扫码关注云+社区

领取腾讯云代金券