Qt通过post请求发送和拆分json数据(二)———附送完整源代码

1,332 阅读3分钟

文章目录

0 背景

因为项目要用到许多的post请求,因此查询了大量资料加上自己的实践,最后总结出了此文。之前也写过相同主题的文章,不过方法比较麻烦,需要通过调用json格式的数据来进行post请求,此文正是上文的优化。这里推荐几个好用的post请求的软件和网址,
软件:Postman
在这里插入图片描述
json数据解析网址

1 发送json格式的数据

1.1 进行post请求的类:

在pro文件中,加入

QT       += network # 网络

.h

#ifndef HTTPNETWORKREQUEST_H
#define HTTPNETWORKREQUEST_H

#include<QNetworkAccessManager>
#include<QNetworkRequest>
#include<QString>
#include<QObject>
#include<QJsonObject>
#include<QByteArray>

class HttpNetworkRequest : public QObject
{
   Q_OBJECT
public:
    HttpNetworkRequest();
    ~HttpNetworkRequest();

private:
    //执行的post类型
    int m_executePostRequestType = 0;
    //解析的post类型
    int m_analysisPostRequestType = 0;

private:
    //post请求状态
    enum PostStatus{
        SucceedDeal = 0,//成功处理
        ServerMaintenanceError = 1,//服务器维护状态
        SeverDisconnectError = 2,//断网状态
        NoPermissionError = 3,//没有权限
        DataAbnormalError = 4,//json数据异常错误
        DealDatabaseError = 5//处理数据库异常错误
    };
    //请求的ip头
    QString m_requestIPHead = "https://baidu.com";
    //解析的post类型
    enum AnalysisPostType{
        TestRequest = 0,//工作模式
    };
    //执行的post类型
    enum ExecutePostType{
        TestOperate = 0,//进货操作
    };


    //得到消息头的token
    QString m_accessToken;
    //发送网络请求和接受应答
    QNetworkAccessManager* m_networkAccessManager;
    //请求的消息题
    QNetworkRequest m_httpRequest;
    //发送data数据
    QByteArray m_sendJsonData;

     /**************请求**********************/
    /**
     * @brief 测试test的post请求
     */
    void testHttpRequestPost();

    /**************处理**********************/

    /**
     * @brief 处理服务器状态请求
     * @param jsonObject
     */
    bool dealTestRequest(QJsonObject& jsonObject);
private slots:
    /**
     * @brief 处理post请求发回的数据的总接口
     * @param reply
     */
    void dealNetworkFinisheded(QNetworkReply *reply);

//调用唯一接口
public slots:

    /**
     * @brief 接收请求操作的post类型
     */
    void receivePostRequestType(int instruct, const QByteArray& content = "");
signals:
    /**
     * @brief 处理数据的结果
     * @param type:界面类型
     * 处理回传参数post,各种异常
     */
    void sendDealDataResult(int result, int type);


};

#endif // HTTPNETWORKREQUEST_H

.cpp

#include "httpnetworkrequest.h"

#include<QJsonObject>
#include<QJsonDocument>
#include<QJsonArray>
#include<QNetworkReply>
#include<QDebug>
#include<QVector>
#include<QDateTime>


/*
消息同步逻辑:
   receivePostRequestType(接收执行消息类型)-->workModeQueryRequestPost(进行工作状态查询)【sendServerMaintainStatus信号】
    --->accessTokenHttpRequestPost--->dealTokenReques(根据m_executePostRequestType类型不同,执行不同业务操作)
*/

HttpNetworkRequest::HttpNetworkRequest()
{

    m_networkAccessManager = new QNetworkAccessManager();
    //处理所有post请求
    connect(m_networkAccessManager, &QNetworkAccessManager::finished,
            this, &HttpNetworkRequest::dealNetworkFinisheded);
}

HttpNetworkRequest::~HttpNetworkRequest()
{
    qDebug()<<"HttpNetworkRequest";
    delete m_networkAccessManager;
}
//发送post请求
void HttpNetworkRequest::testHttpRequestPost()
{
    qDebug()<<"testHttpRequestPost";
//    QJsonObject obj;
//    obj.insert("accountId", "1");
//    QJsonDocument jsonDoc(obj);//QJsonObject转QJsonDocument
//    QString str = QString(jsonDoc.toJson());//QJsonDocument转QString
//    QByteArray content = str.toUtf8();
//    int contentLength = content.length();


    m_httpRequest.setUrl(QUrl(m_requestIPHead + "/api/clientversion/client/working/mode/query"));
    m_httpRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    m_httpRequest.setRawHeader("access_token", m_accessToken.toUtf8());
    m_httpRequest.setHeader(QNetworkRequest::ContentLengthHeader, m_sendJsonData.length());

    m_analysisPostRequestType = AnalysisPostType::TestRequest;
    // 发送参数// 将用户名和密码发送至web服务器进行验证
    m_networkAccessManager->post(m_httpRequest, m_sendJsonData);
}
//处理post请求
bool HttpNetworkRequest::dealTestRequest(QJsonObject &jsonObject)
{
    qDebug()<<"dealTestRequest:"<<jsonObject;
    if(jsonObject.contains("code")){
        if(jsonObject.value("code").toInt() == 200){
            //发送处理结果
            emit sendDealDataResult(PostStatus::SucceedDeal, m_executePostRequestType);
            return true;
        }else{
             emit sendDealDataResult(PostStatus::DataAbnormalError, m_executePostRequestType);
            return false;
        }
    }else{
        emit sendDealDataResult(PostStatus::DealDatabaseError, m_executePostRequestType);
        return false;
    }
}
//post处理总入口
void HttpNetworkRequest::dealNetworkFinisheded(QNetworkReply *reply)
{
    //    if(QSslSocket::supportsSsl() == true){
    //       qDebug()<<"支持SSL:"<<QSslSocket::sslLibraryBuildVersionString() + QSslSocket::sslLibraryVersionString();
    //    }else{
    //        qDebug()<<"不支持SSL:"<<QSslSocket::sslLibraryBuildVersionString() + QSslSocket::sslLibraryVersionString();
    //    }
        QVariant data = reply->readAll();//读取全部数据
        QJsonParseError jsonError;
        QJsonDocument document = QJsonDocument::fromJson(data.toByteArray(), &jsonError);
        if (!document.isNull() && (jsonError.error == QJsonParseError::NoError)) {
              qDebug()<<"解析未发生错误";
                qDebug()<<"JSON 文档为对象";
                  QJsonObject object = document.object();  // 转化为对象
                  if (document.isObject()) {
                      switch (m_analysisPostRequestType) {
                        case AnalysisPostType::TestRequest:
                          dealTestRequest(object);
                          break;
                      default:
                          break;
                      }
                  }else{
                      emit sendDealDataResult(PostStatus::DealDatabaseError, m_executePostRequestType);
                  }
        }else{
            if(document.isNull() == true){
                qDebug()<<"document.isNull:" + reply->errorString();
                emit sendDealDataResult(PostStatus::SeverDisconnectError, m_executePostRequestType);
            }else if(jsonError.error == QJsonParseError::NoError){
               qDebug()<<"jsonError.error:" + reply->errorString();
               emit sendDealDataResult(PostStatus::SeverDisconnectError, m_executePostRequestType);
            }
        }
        //删除对象
        reply->deleteLater();
}


//类接口
void HttpNetworkRequest::receivePostRequestType(int instruct, const QByteArray& content){
    //获得执行的指令
    m_executePostRequestType = instruct;
    //获得发送的内容
    m_sendJsonData = content;

    switch (m_executePostRequestType) {
        case ExecutePostType::TestOperate:
            testHttpRequestPost();
            break;
        default:
            break;
    }
}

1.1 使用post请求类

在类中加入post请求的成员:

#ifndef MAININTERFACE_H
#define MAININTERFACE_H

#include <QMainWindow>
#include"httpnetworkrequest.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainInterface; }
QT_END_NAMESPACE

class MainInterface : public QMainWindow
{
    Q_OBJECT

public:
    MainInterface(QWidget *parent = nullptr);
    ~MainInterface();

private:
    Ui::MainInterface *ui;

private:
    //执行的post类型
    enum ExecutePostType{
        TestOperate = 0,//进货操作
    };
    //post请求
    HttpNetworkRequest* m_httpNetworkRequest;
    /**
     * @brief testPost:调用post方法
     */
    void testPost();
};
#endif // MAININTERFACE_H

.cpp

调用方法:

#include "maininterface.h"
#include "ui_maininterface.h"

#include<QJsonDocument>


MainInterface::MainInterface(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainInterface)
{
    ui->setupUi(this);
    //创建对象
    m_httpNetworkRequest = new HttpNetworkRequest;
    testPost();
}

MainInterface::~MainInterface()
{
    //销毁对象
    delete  m_httpNetworkRequest;
    delete ui;
}
//发送post请求
void MainInterface::testPost()
{
    //要发送的json数据
    QJsonObject obj;
    obj.insert("accountId", "1");
    QJsonDocument jsonDoc(obj);//QJsonObject转QJsonDocument
    QString str = QString(jsonDoc.toJson());//QJsonDocument转QString
    QByteArray content = str.toUtf8();
    //发送post请求
    m_httpNetworkRequest->receivePostRequestType(ExecutePostType::TestOperate, content);
}

2 发送json数据

例如下面的数据:
在这里插入图片描述

方法:

     //要发送的json数据
    QJsonObject sendJsonData;
    sendJsonData.insert("code", 200);
    //加入array
    QJsonArray arry;
    QJsonObject tempObject1;
    tempObject1.insert("name", "小明");
    tempObject1.insert("height", 180);
    tempObject1.insert("weight", 70.3);
    arry.append(tempObject1);
    QJsonObject tempObject2;
    tempObject2.insert("name", "小花");
    tempObject2.insert("height", 165);
    tempObject2.insert("weight", 45.8);
    arry.append(tempObject2);
    sendJsonData.insert("people", QJsonValue(arry));
    //加入object
    QJsonObject tempObject;
    tempObject.insert("school", "Carnegie Mellon University");
    tempObject.insert("location", "PIT");
    sendJsonData.insert("affiliation", QJsonValue(tempObject));

    m_jsonData = sendJsonData;//m_jsonData为类成员变量,类型为QJsonObject
    qDebug()<<"sendJsonData:"<<sendJsonData;

处理post返回的结果:

    //处理post返回的结果
    connect(m_httpNetworkRequest, &HttpNetworkRequest::sendDealDataResult,
            this, [&](int result, int type){
        
    });

3 解析json数据

例如解析上面的示例中的json数据:

    //解析code
    if(m_jsonData.contains("code")){
        qDebug()<<"code:"<<m_jsonData.value("code").toInt();
    }
    //解析array
    if(m_jsonData.contains("people")){
      QJsonValue peopleObject = m_jsonData.take("people");
      if(peopleObject.isArray()){
          QJsonArray peopleArray = peopleObject.toArray();
          for(int i = 0;i < peopleArray.size();++i){
              QJsonValue value = peopleArray.at(i);
              qDebug()<<"name:"<<value["name"].toString();
              qDebug()<<"height:"<<value["height"].toInt();
              qDebug()<<"weight:"<<value["weight"].toDouble();
          }
      }
    }
    //解析obect
    if(m_jsonData.contains("affiliation")){
        QJsonValue affiliationValue = m_jsonData.value("affiliation");
        QJsonObject affiliationObject = affiliationValue.toObject();
        if(affiliationObject.contains("school")){
            qDebug()<<"school:"<<affiliationObject.value("school").toString();
            qDebug()<<"location:"<<affiliationObject.value("location").toString();
        }
    }

4 附赠

github
码云地址
csdn资源(有积分的可以支持一下,谢谢)