赞
踩
学习arm过程中,需要使用httpserver,在这过程中找到了QtWebApp这个轻量级的C++服务器,记录学习的过程。
参考教程:
【1】QtWebAPP官方的教程(官方,详细)Writing web server applications with QtWebApphttp://stefanfrings.de/qtwebapp/tutorial/index.html
【2】国内学习QtWebApp的学习记录(国内写的很好的)https://hpzwl.blog.csdn.net/article/details/130631547https://hpzwl.blog.csdn.net/article/details/130631547
官方下载:http://www.stefanfrings.de/qtwebapp/QtWebApp.zip
解压后的文件:
我这里打开Demo1的项目,使用Qtcreator运行(代码对IDE没有要求,使用vstudio最好,我这里只是顺手了!)
访问的地址为本地的iP地址,修改IP地址需要修改配置文件/etc/Demo1.ini的配置文件
QtWepApp的模块有好几个,为了清楚每一个功能,从头开始一个新的项目进行搭建,逐步添加功能模块。
新建控制台程序,项目名称这里命名为TestQtWeb
新建Modules模块文件夹,将QtWebApp官方项目中的httpserver复制进去,符合模块化设计
在工程pro文件,添加引用第三方的模块,注意路径
新建一个HttpServerManager的类用来实现自己想要的功能
步骤:模块化设计,在Modules新建httpservermanager文件夹,新建txt文件重命名为httpservermanager.pri,在pro中添加httpservermanager模块
添加配置文件ini,这里的ini可以自己写,这里偷懒直接用官方的Demo1中的ini文件
新建etc文件夹,将Demo中的ini文件复制进去
在工程pro文件添加OTHER_FILES将etc下面文件全部加入,这样就可以在IDE显示ini文件了
基础模块搭建好
这里以消息处理实验,继承HttpRequestHandler的类实现
新建HelloWorldHandler类并继承HttpRequestHandler
警告报错,引入头文件,加入命名空间,做一些基础处理
重点是实现service服务接口
在自己写的类中添加Server函数
main.cpp中添加监听事件,在main函数中添加helloworldhandler头文件找不到,在pri文件中添加includepath的路径
运行的结果
错误原因:中文显示是设置了utf-8
解决:
核心代码:
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());
- }
将QtWebApp中的logging,复制到新建的Modules文件夹内,符合模块化设计准则
在工程文件pro添加模块
include($$PWD/Modules/logging/logging.pri)
创建日志文件夹,并新建文本文件命名为demo1.log的文档
在pro文件中添加logs文件夹,这样显示logs下面的文件
OTHER_FILES=etc/* logs/*
修改配置ini文件,将日志路径放出来,并设置新建的文本log文件
main函数引用头文件,开启监听
运行结果的截图
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();
- }
添加前端页面的过程中,需要考虑访问的不同地址所对应的不同页面的呈现,例如访问:http://127.0.0.1/login和http://127.0.0.1/index需要访问不同的页面渲染,这里需要一个请求映射器,也就是根据转换一下不同的请求响应不同的响应。
添加映射器的类RequestMapper,继承HttpRequestHandler
报错,缺少头文件和命名空间,添加即可
添加server函数,针对不同的URL的请求进行不同的reponse
修改main函数中的监听为主映射的类即可
处理不同的响应结果:
核心代码:
- 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中映射器的处理:
什么是Ajax?参考:https://blog.csdn.net/weixin_50602266/article/details/121910781
简单说,Ajax实现的功能局部刷新网页的内容,使用只有五个步骤:
新建一个index.html的页面,包含实现Ajax的功能js,和前面一样就是将写好的html页面通过response发送给浏览器
index.html代码
将html的文件发送给浏览器,通过对ajax的路径来映射处理的逻辑
运行结果:
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的代码
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。