前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Qt开源网络库[2]-接口篇

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

作者头像
Qt君
发布2019-07-15 15:25:34
1.5K0
发布2019-07-15 15:25:34
举报
文章被收录于专栏:跟Qt君学编程跟Qt君学编程

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

1. 接口目录文件列表:

代码语言:javascript
复制
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头文件源代码:

代码语言:javascript
复制
#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类头文件源代码:

代码语言:javascript
复制
#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头信息;

代码语言:javascript
复制
request.header("Last-Modified", "1994-05-07 08:49:37");

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

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

代码语言:javascript
复制
原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>该槽函数的定义也是有限制的目前只支持这三种槽函数定义方式:

代码语言:javascript
复制
void function(QVariantMap resultMap) //function为用户定义函数的名字
void function(QByteArray resultData) //function为用户定义函数的名字
void function(QNetworkReply* reply)  //function为用户定义函数的名字

<2>用法:

代码语言:javascript
复制
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操作.

代码语言:javascript
复制
m_service.get("http:/www.baidu.com")
         .onResponse(this, SLOT(finish(QByteArray)))
         .onError(this, SLOT(error(QNetworkReply::NetworkError, QNetworkReply*)))
         .exec();

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

代码语言:javascript
复制
void function(qint64 bytesReceived, qint64 bytesTotal);

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

示例:

代码语言:javascript
复制
m_service.get("http:/www.baidu.com")
         .onResponse(this, SLOT(downloadProgress(qint64, qint64)))
         .onError(this, SLOT(error(QNetworkReply::NetworkError, QNetworkReply*)))
         .exec();

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

代码语言:javascript
复制
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类头文件源代码:

代码语言:javascript
复制
#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枚举即可

代码语言:javascript
复制
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为真,则第三个参数不需要填写即可自动推导.这里描述得有点抽象但后续文章会重点写到,有兴趣的可以关注一下.

代码语言:javascript
复制
HttpRequest &onResponse(const QObject *receiver, const char *slot, HttpResponse::SupportMethod type)
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-12-01,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档