Qt封装Http请求工具类
一、概述
封装一个HttpUtils工具类,此列封装了Qt的Http请求。总共封装了两个方法Get和Post方法。
二、代码示例
1.工具类:HttpUtils.h/HttpUtils.cpp
#pragma once #include <QObject> #include <QJsonObject> #include <QJsonDocument> #include <QNetworkRequest> #include <QNetworkAccessManager> #include <QNetworkReply> #include <QEventLoop> #include <QString> #include <QMap> #include <functional> #include "CacheUtils.h" //Qt的Http请求的工具类 class HttpUtils : public QObject { Q_OBJECT public: HttpUtils(QObject *parent); ~HttpUtils(); public: void post(QString url,QMap<QString,QString> param, QMap<QString, QString> headers, std::function<void(int, int, QString, QJsonObject)> onResponseResult); void get(QString url, QMap<QString, QString> headers, std::function<void(int, int, QString, QJsonObject)> onResponseResult); };
HttpUtils.cpp
#include "HttpUtils.h" HttpUtils::HttpUtils(QObject* parent) : QObject(parent) { } void HttpUtils::get(QString url, QMap<QString, QString> headers, std::function<void(int, int, QString, QJsonObject)> onResponseResult) { //http请求 QNetworkRequest request;//用于设置请求参数,如:请求头、请求URL等 QNetworkAccessManager nam;//用于发起网络请求,如POST、GET //由于请求发生重定向,所以要加上这行代码,设置自动跳转,否则会返回 302 request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); request.setUrl(url); connect(&nam, &QNetworkAccessManager::finished, this, [=](QNetworkReply* reply) {//自定义槽函数用于接收网络请求完成后的数据 //获取Http请求响应状态码 QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute); if (statusCode.isValid()) { qDebug() << "Http请求状态码 = " << statusCode.toInt(); } //获取响应源语 QVariant reason = reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString(); if (reason.isValid()) { qDebug() << "Http请求响应源语=" << reason.toString(); } //网络请求错误 QNetworkReply::NetworkError err = reply->error(); QByteArray res = reply->readAll(); QJsonObject doc = QJsonDocument::fromJson(res).object(); if (err == QNetworkReply::NoError) {//表示网络请求没有错误 QString ip = doc.value("ip").toString(); int code = doc.value("code").toInt(); QString message = doc.value("message").toString(); qDebug() << "IP地址:" << ip; qDebug() << "code:" << code; qDebug() << "message:" << message; if (code == 200) {//请求正常输出token的值,存储本地,然后表示登录成功 QJsonObject mData = doc.value("data").toObject(); QString token = mData.value("key").toString(); CacheUtils::getInstance().setToken(token); qDebug() << "token:" << token; //QMessageBox::information(this, "信息", "token的值为" + token); } else { //QMessageBox::critical(this, "错误", message); } onResponseResult(statusCode.toInt(), code, message, doc); //QString qDebug() << "输出网络请求的整体响应结果:" << res << endl; } else { qDebug() << "网络请求发生异常"; onResponseResult(statusCode.toInt(), -1, reason.toString(), doc); } //请求完成后释放reply对象 reply->deleteLater(); }); //设置网络请求的URL request.setUrl(QUrl(url)); //请求头token设置 request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json; charset=UTF-8")); for (auto& pair : headers.toStdMap()) { request.setRawHeader(pair.first.toStdString().c_str(), pair.second.toStdString().c_str()); } qDebug() << "请求方式:Get"; QNetworkReply* reply = nam.get(request); //post请求头+传输的数据 //开启事件循环,直到请求完成 QEventLoop loop; connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); loop.exec(); } //http://192.168.100.12:8384/aic-user/sso/login void HttpUtils::post(QString url, QMap<QString, QString> param, QMap<QString, QString> headers, std::function<void(int, int, QString, QJsonObject)> onResponseResult) { //http请求 QNetworkRequest request;//用于设置请求参数,如:请求头、请求URL等 QNetworkAccessManager nam;//用于发起网络请求,如POST、GET //准备登录数据:用户名和密码,并存入JSONObject中 QJsonObject dataObj; for (auto& pair : param.toStdMap()) { dataObj.insert(pair.first, pair.second); } //将数据存入json文档 QJsonDocument document; document.setObject(dataObj); //转换成QByteArray方便下面使用 QByteArray byteArray = document.toJson(QJsonDocument::Compact);//类型转换 connect(&nam, &QNetworkAccessManager::finished, this, [=](QNetworkReply* reply) {//自定义槽函数用于接收网络请求完成后的数据 //获取Http请求响应状态码 QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute); if (statusCode.isValid()) { qDebug() << "Http请求状态码 = " << statusCode.toInt(); } //获取响应源语 QVariant reason = reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString(); if (reason.isValid()) { qDebug() << "Http请求响应源语=" << reason.toString(); } //网络请求错误 QNetworkReply::NetworkError err = reply->error(); QByteArray res = reply->readAll(); QJsonObject doc = QJsonDocument::fromJson(res).object(); if (err == QNetworkReply::NoError) {//表示网络请求没有错误 QString ip = doc.value("ip").toString(); int code = doc.value("code").toInt(); QString message = doc.value("message").toString(); qDebug() << "IP地址:" << ip; qDebug() << "code:" << code; qDebug() << "message:" << message; if (code == 200) {//请求正常输出token的值,存储本地,然后表示登录成功 QJsonObject mData = doc.value("data").toObject(); QString token = mData.value("key").toString(); CacheUtils::getInstance().setToken(token); qDebug() << "token:" << token; //QMessageBox::information(this, "信息", "token的值为" + token); } else { //QMessageBox::critical(this, "错误", message); } onResponseResult(statusCode.toInt(), code, message, doc); //QString qDebug() << "输出网络请求的整体响应结果:" << res << endl; } else { qDebug() << "网络请求发生异常"; onResponseResult(statusCode.toInt(), -1, reason.toString(), doc); } //请求完成后释放reply对象 reply->deleteLater(); }); //设置网络请求的URL request.setUrl(QUrl(url)); //请求头token设置 request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json; charset=UTF-8")); for (auto& pair : headers.toStdMap()) { request.setRawHeader(pair.first.toStdString().c_str(), pair.second.toStdString().c_str()); } qDebug() << "请求头:"; qDebug() << "请求内容:" << byteArray.toStdString().c_str(); qDebug() << "请求方式:Post"; QNetworkReply* reply = nam.post(request, byteArray); //post请求头+传输的数据 //开启事件循环,直到请求完成 QEventLoop loop; connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); loop.exec(); } HttpUtils::~HttpUtils() { }
2.使用上述工具类做一个登录和获取用户信息的功能
LoginWindow.h
#pragma once #include <QWidget> #include "../../common/edittext/EditText.h" #include "../../common/button/Button.h" #include <QMessageBox> #include "utils/HttpUtils.h" #include <QFormLayout> class LoginWindow : public QWidget { Q_OBJECT public: LoginWindow(QWidget *parent = nullptr); ~LoginWindow(); void login(QString username, QString password); void getUserInfo(); private: EditText* etUserName; EditText* etPassword; Button* btnLogin; HttpUtils *httpUtils; };
LoginWindow.cpp
#include "LoginWindow.h" LoginWindow::LoginWindow(QWidget* parent) : QWidget(parent) { httpUtils = new HttpUtils(this); this->setWindowTitle("登录"); etUserName = new EditText(this); etUserName->setPlaceholderText("请输入用户名"); etPassword = new EditText(this); etPassword->setPlaceholderText("请输入密码"); btnLogin = new Button(this); btnLogin->setText("登录"); QFormLayout* formLayout = new QFormLayout(this); formLayout->addRow(tr("用户名:"), etUserName); formLayout->addRow(tr("密 码:"), etPassword); formLayout->addRow(btnLogin); //formLayout->setMargin(50); formLayout->setVerticalSpacing(20); formLayout->setContentsMargins(50, 50, 50, 200); this->setLayout(formLayout); connect(btnLogin, &Button::clicked, [=]() { const QString username = etUserName->text(); const QString password = etPassword->text(); if (username.isEmpty()) { QMessageBox::warning(this, "温馨提示", "用户名不能为空"); } else if (password.isEmpty()) { QMessageBox::warning(this, "温馨提示", "用户密码不能为空"); } else { login(QString(username), QString(password)); } }); } void LoginWindow::login(QString username, QString password) { QMap<QString, QString> param; param.insert("username", username); param.insert("password", password); QMap<QString, QString> headers; headers.insert("Authorization", ""); headers.insert("appVersion", "1.0.0"); headers.insert("apiVersion", "1.0"); headers.insert("channel", "android"); headers.insert("deviceType", "2"); headers.insert("deviceCode", "8f6f465f-e91d-4a97-8f4e-e6a410e4f0e7_android_1702617469162"); headers.insert("deviceName", "LNA-AL00"); httpUtils->post("http://192.168.10.12:8080/xxxxx/xxx/login", param, headers, [=](int statusCode, int code, QString msg, QJsonObject result) { if (code == 200) { QMessageBox::critical(this, "提示", "登录成功"); getUserInfo(); } else { QMessageBox::critical(this, "提示", "登录失败"); } }); } //根据token获取用户信息 void LoginWindow::getUserInfo() { QMap<QString, QString> headers; headers.insert("Authorization", "Bearer " + CacheUtils::getInstance().getToken()); headers.insert("appVersion", "1.0.0"); headers.insert("apiVersion", "1.0"); headers.insert("channel", "android"); headers.insert("deviceType", "2"); headers.insert("deviceCode", "8f6f465f-e91d-4a97-8f4e-e6a410e4f0e7_android_1702617469162"); headers.insert("deviceName", "LNA-AL00"); httpUtils->get("http://192.168.10.12:8080/xxxx/xxxx/detail", headers, [=](int statusCode, int code, QString msg, QJsonObject result) { if (code == 200) { QMessageBox::critical(this, "提示", "获取用户信息成功"); } else { QMessageBox::critical(this, "提示", "获取用户信息失败"); } }); } LoginWindow::~LoginWindow() { }
分类:
C/C++
, Qt / Qt网络编程
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
2014-01-03 Java JDK1.5、1.6、1.7新特性整理