小言_互联网的博客

Linux QT 4G发送HTTP POST请求发送JSON格式的数据

444人阅读  评论(0)

接上一篇文章:Linux下4G模块高新兴物联中兴ME3630拨号上网
4G网络打通以后,接下来就可以上传和接收数据啦!有点小兴奋!
我们来看看QT上如何来发送一个HTTP的POST请求。

HTTP协议在这里就不多说了,百度自己看。

一、在PC Window(QT5版本)

1.1、构建URL

1.2、构建HTTP请求头

1.3、连接信号与操作,接收服务器回复的消息


槽函数这里我们要在头文件定义,然后把处理过程实现。

void MainWindow::replyFinished(QNetworkReply *reply)
{
    char recvbuffer[128] ;
    memset(recvbuffer,0,128);
    //1、获取响应状态码
    variant = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
    if (variant.isValid())
        qDebug() << variant.toInt();
    //2、获取响应头
    variant = reply->header(QNetworkRequest::ContentTypeHeader);
    if (variant.isValid())
        qDebug() << variant.toString();
    //3、获取响应信息
    QByteArray bytes = reply->readAll();
    qDebug() << bytes ;
    
    QJsonValue success_value ;
    QJsonValue message_value ;
    QJsonParseError jsonError;
    //转换为Json文档
    QJsonDocument doucment = QJsonDocument::fromJson(bytes, &jsonError);
    //解析时没有发生错误
    if (!doucment.isNull() && (jsonError.error == QJsonParseError::NoError))
    {
        if (doucment.isObject()) { // JSON 文档为对象
            {
                // 转化为对象
                QJsonObject object = doucment.object();
                // 包含指定的 key
                if (object.contains("success")) {
                    // 获取指定 key 对应的 value
                    success_value = object.value("success");
                    qDebug() << "success_value : " << success_value.toBool();
                }
                // 包含指定的 key
                if (object.contains("message")) {
                    // 获取指定 key 对应的 value
                    message_value = object.value("message");
                    qDebug() << "message_value : " << message_value.toString();
                }

            }
        }
    }

    if(true == success_value.toBool())
    {
        qDebug() << "数据上传成功";
    }
}

至于处理过程为什么要去JSON格式的数据,那是根据我的服务器给我返回的消息来进行处理的,其中最重要的是readAll得到的响应消息,服务器给我回复的是JSON格式的数据,所以我就要以JSON的格式去解析这个数据。

那当然,如果你想玩,就跟AT指令一样,服务器回个OK\r\n给我也可以啊。。。哈哈哈,没毛病。

1.4、构造要发送的JSON数据


构造的结果就是===> "{\"detail\":\"1\",\"type\":\"2\"}"

1.5、发送POST请求


源码实现如下:
mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <unistd.h>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // URL
    baseUrl = "http://120.78.136.134:9002/api/explosive/messages";
    QUrl url(baseUrl);

    // 构造Json数据
    json.insert("type", "2");
    json.insert("detail", "1");
    QJsonDocument document;
    document.setObject(json);
    dataArray = document.toJson(QJsonDocument::Compact);

    // 构造请求头
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    request.setUrl(url);
    manager = new QNetworkAccessManager(this);
    // 连接信号槽
    connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(replyFinished(QNetworkReply *)));


    dataArray = "{\"detail\":\"1\",\"type\":\"2\"}" ;
    qDebug() << dataArray ;
    // 发送请求
    manager->post(request, dataArray);
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::replyFinished(QNetworkReply *reply)
{
    //1、获取响应状态码
    variant = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
    if (variant.isValid()){
        qDebug() << variant.toInt() ;
    }
    //2、获取响应头
    variant = reply->header(QNetworkRequest::ContentTypeHeader);
    if (variant.isValid())
        qDebug() << variant.toString();

    //3、获取响应信息
    QByteArray bytes = reply->readAll();
    qDebug() << bytes ;
    ui->textBrowser->append(bytes);

    QJsonValue success_value ;
    QJsonValue message_value ;
    QJsonParseError jsonError;
    //转换为Json文档
    QJsonDocument doucment = QJsonDocument::fromJson(bytes, &jsonError);
    //解析时没有发生错误
    if (!doucment.isNull() && (jsonError.error == QJsonParseError::NoError))
    {
        if (doucment.isObject()) { // JSON 文档为对象
            {
                // 转化为对象
                QJsonObject object = doucment.object();
                // 包含指定的 key
                if (object.contains("success")) {
                    // 获取指定 key 对应的 value
                    success_value = object.value("success");
                    qDebug() << "success_value : " << success_value.toBool();
                }
                // 包含指定的 key
                if (object.contains("message")) {
                    // 获取指定 key 对应的 value
                    message_value = object.value("message");
                    qDebug() << "message_value : " << message_value.toString();
                }

            }
        }
    }

    if(true == success_value.toBool())
    {
        qDebug() << "数据上传成功";
    }
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QtNetwork>
#include <QDebug>
#include <QString>
#include <QVariant>
#include <QHttpMultiPart>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

public slots:
    void replyFinished(QNetworkReply *reply);

private:
    Ui::MainWindow *ui;
    QString baseUrl ;
    QJsonObject json;
    QByteArray dataArray ;
    QNetworkRequest request;
    QNetworkAccessManager *manager ;
    QVariant variant ;
};

#endif // MAINWINDOW_H

1.6、在PC上的运行结果


数据成功上传。

二、在PC Linux下需要注意的地方

貌似没有QT JSON的库,所以一用到Json相关库的时候会报找不到当前头文件或者库的错。那也很简单,把上面所有JSON相关的操作函数以及头文件去掉,当我要构建一个JSON数据然后发起post请求的时候只需要:

QByteArray dataArray = "{\"detail\":\"1\",\"type\":\"2\"}" ;
manager->post(request, dataArray);

这样跟JSON库做的方法是一样的,当然你可以百度去下第三方的JSON库,一样也可以实现。
将程序交叉编译后,在周立功的ARM A6G2C(imx6ul上运行)
mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QtNetwork>
#include <QDebug>
#include <QString>
#include <QVariant>
#include <QHttpMultiPart>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

public slots:
    void replyFinished(QNetworkReply *reply);

private:
    Ui::MainWindow *ui;
    QString baseUrl ;
    //QJsonObject json;
    QByteArray dataArray ;
    QNetworkRequest request;
    QNetworkAccessManager *manager ;
    QVariant variant ;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <unistd.h>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // URL
    baseUrl = "http://120.78.136.134:9002/api/explosive/messages";
    QUrl url(baseUrl);

    // 构造请求头 ===>  包括三个部分 请求方式(POST)、请求URL(baseUrl)、HTTP协议及版本(HTTP/1.1)
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    request.setUrl(url);
    manager = new QNetworkAccessManager(this);
    // 连接信号槽
    connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(replyFinished(QNetworkReply *)));
    //// 构造Json数据
    dataArray = "{\"detail\":\"1\",\"type\":\"2\"}" ;
    // 发送请求
    manager->post(request, dataArray);
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::replyFinished(QNetworkReply *reply)
{
    char recvbuffer[128] ;
    memset(recvbuffer,0,128);
    //1、获取响应状态码
    variant = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
    if (variant.isValid()){
        sprintf(recvbuffer,"HTTP/1.1 %d OK",variant.toInt());
        qDebug() << recvbuffer ;
    }
    //2、获取响应头
    variant = reply->header(QNetworkRequest::ContentTypeHeader);
    if (variant.isValid())
        qDebug() << variant.toString();

    //3、获取响应信息
    QByteArray bytes = reply->readAll();
    qDebug() << bytes ;
    ui->textBrowser->append(bytes);
}

在周立功ARM平台上的运行结果,在执行程序之前需要做如下的操作:

拨号上网

查看ppp节点

测试网络连通性

执行HTTP测试程序


数据成功上传。


转载:https://blog.csdn.net/morixinguan/article/details/102455607
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场