Qt+HttpServer的学习记录

这篇具有很好参考价值的文章主要介绍了Qt+HttpServer的学习记录。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

学习arm过程中,需要使用httpserver,在这过程中找到了QtWebApp这个轻量级的C++服务器,记录学习的过程。

参考教程:https://hpzwl.blog.csdn.net/article/details/130631547 (写的详细,推荐)

代码下载地址

官方下载:http://www.stefanfrings.de/qtwebapp/QtWebApp.zip

Qt+HttpServer的学习记录,Qt,学习,qt 

解压后的文件:

Qt+HttpServer的学习记录,Qt,学习,qt

学习过程 

官方Demo项目运行结果

我这里打开Demo1的项目,使用Qtcreator运行(代码对IDE没有要求,使用vstudio最好,我这里只是顺手了!)

访问的地址为本地的iP地址,修改IP地址需要修改配置文件/etc/Demo1.ini的配置文件

Qt+HttpServer的学习记录,Qt,学习,qt

 

 Qt的HttpServer模块搭建过程

QtWepApp的模块有好几个,为了清楚每一个功能,从头开始一个新的项目进行搭建,逐步添加功能模块。

1、添加核心的Httpserver模块 

新建控制台程序,项目名称这里命名为TestQtWeb

Qt+HttpServer的学习记录,Qt,学习,qt

Qt+HttpServer的学习记录,Qt,学习,qt 

新建Modules模块文件夹,将QtWebApp官方项目中的httpserver复制进去,符合模块化设计

Qt+HttpServer的学习记录,Qt,学习,qt

在工程pro文件,添加引用第三方的模块,注意路径

Qt+HttpServer的学习记录,Qt,学习,qt

 新建一个HttpServerManager的类用来实现自己想要的功能

步骤:模块化设计,在Modules新建httpservermanager文件夹,新建txt文件重命名为httpservermanager.pri,在pro中添加httpservermanager模块

Qt+HttpServer的学习记录,Qt,学习,qt

Qt+HttpServer的学习记录,Qt,学习,qt

添加配置文件ini,这里的ini可以自己写,这里偷懒直接用官方的Demo1中的ini文件

新建etc文件夹,将Demo中的ini文件复制进去

Qt+HttpServer的学习记录,Qt,学习,qt

在工程pro文件添加OTHER_FILES将etc下面文件全部加入,这样就可以在IDE显示ini文件了

Qt+HttpServer的学习记录,Qt,学习,qt

基础模块搭建好

这里以消息处理实验,继承HttpRequestHandler的类实现

新建HelloWorldHandler类并继承HttpRequestHandler

Qt+HttpServer的学习记录,Qt,学习,qt

Qt+HttpServer的学习记录,Qt,学习,qt 警告报错,引入头文件,加入命名空间,做一些基础处理

Qt+HttpServer的学习记录,Qt,学习,qt

重点是实现service服务接口

Qt+HttpServer的学习记录,Qt,学习,qt

 在自己写的类中添加Server函数

Qt+HttpServer的学习记录,Qt,学习,qt

main.cpp中添加监听事件,在main函数中添加helloworldhandler头文件找不到,在pri文件中添加includepath的路径

Qt+HttpServer的学习记录,Qt,学习,qt

运行的结果

Qt+HttpServer的学习记录,Qt,学习,qt

错误原因:中文显示是设置了utf-8

解决:

Qt+HttpServer的学习记录,Qt,学习,qt

核心代码:

main.cpp

#include <QCoreApplication>
#include <QDir>
#include <QSettings>
#include "httplistener.h"
#include "helloworldhandler.h"

using namespace  stefanfrings;

/** 寻找ini配置文件,可以理解为向上下路径找ini文件 */
QString searchConfigFile()
{
    QString binDir=QCoreApplication::applicationDirPath();
    QString appName=QCoreApplication::applicationName();
    QString fileName("Demo1.ini");

    QStringList searchList;
    searchList.append(binDir);
    searchList.append(binDir+"/etc");
    searchList.append(binDir+"/../etc");
    searchList.append(binDir+"/../"+appName+"/etc");     // for development with shadow build (Linux)
    searchList.append(binDir+"/../../"+appName+"/etc");  // for development with shadow build (Windows)
    searchList.append(QDir::rootPath()+"etc/opt");
    searchList.append(QDir::rootPath()+"etc");

    foreach (QString dir, searchList)
    {
        QFile file(dir+"/"+fileName);
        if (file.exists())
        {
            fileName=QDir(file.fileName()).canonicalPath();
            qDebug("Using config file %s",qPrintable(fileName));
            return fileName;
        }
    }

    // not found
    foreach (QString dir, searchList)
    {
        qWarning("%s/%s not found",qPrintable(dir),qPrintable(fileName));
    }
    qFatal("Cannot find config file %s",qPrintable(fileName));
    return nullptr;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    a.setApplicationName("TestQtWeb");
    QString configFileName=searchConfigFile();

    // 开启http监听
    QSettings* listenerSettings=new QSettings(configFileName,QSettings::IniFormat,&a);
    listenerSettings->beginGroup("listener");
    new HttpListener(listenerSettings,new HelloWorldHandler(&a),&a);

    return a.exec();
}

helloworldhandler.h

#ifndef HELLOWORLDHANDLER_H
#define HELLOWORLDHANDLER_H

#include    "httprequesthandler.h"

using namespace stefanfrings;


class HelloWorldHandler : public HttpRequestHandler
{
public:
    HelloWorldHandler(QObject* parent=nullptr);
    void service(HttpRequest& request, HttpResponse& response);
};

#endif // HELLOWORLDHANDLER_H

 helloworldhandler.cpp

#include "helloworldhandler.h"

HelloWorldHandler::HelloWorldHandler(QObject* parent):HttpRequestHandler(parent)
{

}

void HelloWorldHandler::service(HttpRequest &request, HttpResponse &response)
{
    //添加中文,就是想试一试是否会乱码!
    QString temp="Hello,World! 我的名字是WH!";
    response.write(temp.toUtf8());
}

2、添加日志模块 

将QtWebApp中的logging,复制到新建的Modules文件夹内,符合模块化设计准则

Qt+HttpServer的学习记录,Qt,学习,qt

在工程文件pro添加模块

include($$PWD/Modules/logging/logging.pri)

 创建日志文件夹,并新建文本文件命名为demo1.log的文档

Qt+HttpServer的学习记录,Qt,学习,qt

 在pro文件中添加logs文件夹,这样显示logs下面的文件

OTHER_FILES=etc/* logs/*

 修改配置ini文件,将日志路径放出来,并设置新建的文本log文件

Qt+HttpServer的学习记录,Qt,学习,qt

main函数引用头文件,开启监听

Qt+HttpServer的学习记录,Qt,学习,qt

运行结果的截图

Qt+HttpServer的学习记录,Qt,学习,qt

main全部代码 

#include <QCoreApplication>
#include <QDir>
#include <QSettings>
#include "httplistener.h"
#include "helloworldhandler.h"
#include "filelogger.h"
using namespace  stefanfrings;

/** 寻找ini配置文件,可以理解为向上下路径找ini文件 */
QString searchConfigFile()
{
    QString binDir=QCoreApplication::applicationDirPath();
    QString appName=QCoreApplication::applicationName();
    QString fileName("Demo1.ini");

    QStringList searchList;
    searchList.append(binDir);
    searchList.append(binDir+"/etc");
    searchList.append(binDir+"/../etc");
    searchList.append(binDir+"/../"+appName+"/etc");     // for development with shadow build (Linux)
    searchList.append(binDir+"/../../"+appName+"/etc");  // for development with shadow build (Windows)
    searchList.append(QDir::rootPath()+"etc/opt");
    searchList.append(QDir::rootPath()+"etc");

    foreach (QString dir, searchList)
    {
        QFile file(dir+"/"+fileName);
        if (file.exists())
        {
            fileName=QDir(file.fileName()).canonicalPath();
            qDebug("Using config file %s",qPrintable(fileName));
            return fileName;
        }
    }

    // not found
    foreach (QString dir, searchList)
    {
        qWarning("%s/%s not found",qPrintable(dir),qPrintable(fileName));
    }
    qFatal("Cannot find config file %s",qPrintable(fileName));
    return nullptr;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    a.setApplicationName("TestQtWeb");
    QString configFileName=searchConfigFile();

    // 开启日志
    QSettings* logSettings=new QSettings(configFileName,QSettings::IniFormat,&a);
    logSettings->beginGroup("logging");
    FileLogger* logger=new FileLogger(logSettings,10000,&a);
    logger->installMsgHandler();

    // 开启http监听
    QSettings* listenerSettings=new QSettings(configFileName,QSettings::IniFormat,&a);
    listenerSettings->beginGroup("listener");
    new HttpListener(listenerSettings,new HelloWorldHandler(&a),&a);


    return a.exec();
}

3、添加HTML交互页面

添加前端页面的过程中,需要考虑访问的不同地址所对应的不同页面的呈现,例如访问:http://127.0.0.1/login和http://127.0.0.1/index需要访问不同的页面渲染,这里需要一个请求映射器,也就是根据转换一下不同的请求响应不同的响应。

添加映射器的类RequestMapper,继承HttpRequestHandler

报错,缺少头文件和命名空间,添加即可

Qt+HttpServer的学习记录,Qt,学习,qt添加server函数,针对不同的URL的请求进行不同的reponse

Qt+HttpServer的学习记录,Qt,学习,qt

修改main函数中的监听为主映射的类即可

Qt+HttpServer的学习记录,Qt,学习,qt

处理不同的响应结果:

Qt+HttpServer的学习记录,Qt,学习,qt

 核心代码:

void RequestMapper::service(HttpRequest &request, HttpResponse &response)
{

        QString str;
        QString path = request.getPath();

        if(path == "/")
        {
            str += "<!DOCTYPE html>"
                   "<html lang=\"zh-cn\">"
                   "<head>"
                   "<meta charset=\"UTF-8\">"
                   "<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">"
                   "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">"
                   "<title>QtWebServer</title>"
                   "</head>"
                   "<body>"
                   "    <p>你好,今天是2024.01.17</p>"
                   "    <p><a href=\"helloworld\">Hello world!</a></p>"
                   "    <p><a href=\"login\">login</a></p>"
                   "</body>";
        }else if(path == "/login")
        {
            str += "<!DOCTYPE html>"
                   "<html lang=\"zh-cn\">"
                   "<head>"
                   "<meta charset=\"UTF-8\">"
                   "<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">"
                   "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">"
                   "<title>QtWebServer</title>"
                   "</head>"
                   "<body>"
                   "    <p>登录</p>"
                   "    <p>Success!</p>"
                   "    <p><a href=\"\\\">返回</a></p>"
                   "</body>";

        }else if(path == "/helloworld")
        {

            str += "<!DOCTYPE html>"
                   "<html lang=\"zh-cn\">"
                   "<head>"
                   "<meta charset=\"UTF-8\">"
                   "<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">"
                   "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">"
                   "<title>QtWebServer</title>"
                   "</head>"
                   "<body>"
                   "    <p>hello</p>"
                  "    <p><a href=\"\\\">返回</a></p>"
                   "</body>";
        }else {
            response.setStatus(404,"Not found");
            str = "The URL is wrong, no such document.";
        }

        //这里转换为utf-8的原因是,网页charset设置为utf-8了
        QByteArray byteArray = str.toUtf8();
        response.write(byteArray);



}

这个是最简单的根据不同的路径,将HTML通过reponse发送,将这些HTML页面可以换成不同的响应的控制器control,本质都是一样的!

官方的Demo中映射器的处理

Qt+HttpServer的学习记录,Qt,学习,qt

4、使用ajax与后台数据交互

什么是Ajax?参考:https://blog.csdn.net/weixin_50602266/article/details/121910781

简单说,Ajax实现的功能局部刷新网页的内容,使用只有五个步骤:

Qt+HttpServer的学习记录,Qt,学习,qt 

新建一个index.html的页面,包含实现Ajax的功能js,和前面一样就是将写好的html页面通过response发送给浏览器

index.html代码

Qt+HttpServer的学习记录,Qt,学习,qt

将html的文件发送给浏览器,通过对ajax的路径来映射处理的逻辑

Qt+HttpServer的学习记录,Qt,学习,qt

运行结果:

Qt+HttpServer的学习记录,Qt,学习,qt

 html的代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>首页</title>
    
</head>
<body>
    <h1>欢迎来到首页!</h1>
    <p>这是一个使用QtWeb作为服务器框架搭建的简单网页。</p>
    <p id="ajaxp">这个区域文字用来显示ajax的变化</p>
    <button id="changeImgBtn" onclick="changeImg()" >ajax切换按钮</button>

    <script>
        function changeImg(){
           var xhr=new XMLHttpRequest();
           xhr.open("GET","/ajaxChange",true);
           xhr.send();
           xhr.onreadystatechange=function(){
            if (xhr.readyState==4 && xhr.status==200){
                var ajaxtextP=document.getElementById("ajaxp");
                ajaxtextP.innerHTML=xhr.responseText;
           }
         
          
        }
    }
    
       
    </script>
    
</body>
</html>

requestmanager.cpp的代码文章来源地址https://www.toymoban.com/news/detail-803791.html

到了这里,关于Qt+HttpServer的学习记录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux 学习记录47(QT篇待完成)

    信号与槽机制,是qt的核心机制,能够完成多个组件之间的互相通信,即一个组件发射信号,其他组件用于相应该信号,并做出相应处理工作 信号:信号就是信号函数,可以是组件自身提供,也可以是用户自己定义,自定义时,需要在类体的signals权限下进行定义,并且该函数

    2024年02月13日
    浏览(29)
  • QT学习记录(三)通过ui和代码的方式往窗口添加组件

    本文是b站教程的https://www.bilibili.com/video/BV1g4411H78N?p=5vd_source=a3efe214b8a2ba185e92e79cb6d6321b的笔记,外加自己的一些其他想法。如有侵权请联系。如有错误请指正。 通过拖拽,把一个按钮和一个label拖进去了。 新建了一个按钮对象,并通过setParent指定了父亲就是当前的主窗口。 当

    2024年02月07日
    浏览(32)
  • Qt使用QWebEngineView一些记录

    1.关闭软件警告: Release of profile requested but WebEnginePage still not deleted. Expect troubles! 原因,系统退出关闭view,没有释放page。 解决办法:手动释放page  顺便把view也释放了。 2.获取QWebEngineView点击超链接 重写QWebEngineView中的createWindow函数 3.获取QWebEngineView当前链接 QWebEngineView自带

    2024年02月07日
    浏览(37)
  • 记录一次QT乱码问题

    在敲陆文周的书《QT5开发及实例》的示例代码时,出现乱码,如下图所示 具体代码如下 在阅读csdn大佬急支糖浆的文章后,理解了 源文件码字符集,执行字符集等概念。 源文件编码字符集:源文件保存时的编码方式,如gbk,utf-8等。 执行字符集:编译器编译后的可执行文件

    2024年01月24日
    浏览(27)
  • Qt:记录一下好看的配色

    2024年02月13日
    浏览(31)
  • QT6 for android 安装教程记录(版本Qt6.5.2)

    本文记录首次安装QT for andriod的详细记录。 网上的信息和资料非常多,收集和整理以及遇到的问题也各异,对新手首次接触相关开发和部署环境并不是清晰,因此,特将相关详细配置记录。 首先,开发QT for andriod 不建议使用QT5.15的版本,因为该版本不能区分相关的CPU架构,而

    2024年02月03日
    浏览(38)
  • Linux 打包Qt程序到无Qt环境Linux系统下运行,问题记录

    Linux 环境下Qt开发的摄像头程序用到了opencv的库,需要跟Qt环境一起打包。 1.打包所有关联库用的是脚本程序。 2.新建空文件夹放入编译好的release qt程序,比如摄像头程序 camera,新建打包脚本copylib.sh放在文件夹下。   3.终端执行 ./copylib.sh camera 会打包 camera程序所需的关联库。

    2024年02月16日
    浏览(33)
  • C++/Qt 小知识记录3

    工作中遇到的一些小问题,总结的小知识记录:C++/Qt 生成VS工程后,在这里联动(反知:创建的VS工程里,关于启动exe后是否需要控制台的设置在这里): 实体(Entity) : 主要 由标识定义的对象 。 它可以是任何事物,只要满足两个条件即可,一是它在整个生命周期中具有

    2024年02月05日
    浏览(23)
  • 面试问题记录一 --- C++(Qt方向)

            以下是我于2023年6~7月间换工作时遇到的面试题目,有需要的小伙伴可以参考下。约100个题目。 1       C和C++的区别          1)      文件区别:C源文件后缀 .c;C++源文件后缀 .cpp          2)      返回值: C默认返回int型;C++ 若无返回值,必须指定为

    2024年02月09日
    浏览(32)
  • VS2019社区版和QT安装记录

    下载 VS2019:  Visual Studio 2019 版本 16.11 发行说明 | Microsoft Learn https://learn.microsoft.com/zh-cn/visualstudio/releases/2019/release-notes 选择第一个,下载社区版。或者这里下载。 比较简单的方式就是直接打开,网络安装。但微软提供了先下载,后离线的方法,使得我们可以做一个备份 。

    2024年02月11日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包