演示样例源码下载地址:Fetch_Platform.7z

更复杂的代码可參考本博客BBS的实现

简单的说。动态站点就是能够动态变更的站点。动态变化的内容通常来自后端数据库。例如以下省略万字(动态站点

一个个动态的网页汇集成了一个动态站点,动态网页在一定的模板上由后端局部替换。使得用户看到的内容是随需而变。这里我们忽略掉数据库处理部分,直接实现网页内容的变化,从而了解server端的工作原理。对于你了解整个动态站点的工作过程非常有帮助。

注意:下面过程全都在Windows 7 64上使用Visual C++ 2008 Express编译使用。如使用不同的环境或工具,请高手自行搞定

静态页

动态页

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdGlwbGlw/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

開始使用

IDE

在Visual C++ Express 2008下打开项目方案,

fetch_platform\build\vc2008\fetch_platform.sln,按例如以下图所看到的配置

站点port

站点程序的入口在文件HTTPFormServer.cpp,以下是站点的port。通常为80port。为了避免可能的port冲突。这里使用8020,站点程序执行起来能够使用http://localhost:8020/訪问,

当然假设你电脑上的80port没有被其它程序占用。能够简单的使用http://localhost/进行訪问

            unsigned short port = 8020;
if (args.size() > 0) // change default port
port = (unsigned short) NumberParser::parse(args[0]);

后端

加入服务类

加入一个头文件DemoService.h

#ifndef DEMO_SERVICE_H
#define DEMO_SERVICE_H #include "shared_service.h" class DemoService : public SharedService
{
public:
void handle(Poco::Net::HTTPServerRequest& req, Poco::Net::HTTPServerResponse& resp,
Poco::URI& uri, const std::string& fileName); public:
static const std::string SERVICE_PREFIX; // 用于URL分发 private:
}; #endif // DEMO_SERVICE_H

实现文件DemoService.cpp

#include "demo_service.h"

const std::string DemoService::SERVICE_PREFIX        = "/demo/";

// 凡是地址栏显演示样例如以下的都会进入以下这种方法
// http://domain/demo/***
//
void DemoService::handle(Poco::Net::HTTPServerRequest& req, Poco::Net::HTTPServerResponse& resp,
Poco::URI & uri, const std::string& fileName)
{
// 分类处理demo下不同的请求。然后return
//
// 否则,假设没有特别的处理,将直接调用父类的handle方法 // 作为演示样例。这里没有对DemoService进行扩充,感兴趣能够下载BBS的源码
// 因此这里直接交由父类处理
//
 SharedService::handle(req, resp, uri, fileName);
}

WebServer是怎样将浏览器的请求转发到DemoService的?

答案就在ServiceDispatcher类。详细例如以下

    // demo service
if (startsWith(fileName, DemoService::SERVICE_PREFIX))
{
DemoService demo;
demo.handle(req, resp, uri, fileName);
return;
}

加入标签类

标签类负责动态替换模板里的内容,这里的标签最重要的部分就是标签名,必须保证唯一性

标签类必须与.jsp前端网页配合使用才干实现动态显示网页的效果

头文件

#ifndef DEMO_TAG_H
#define DEMO_TAG_H #include "Poco/Net/base_tag.h" class DemoTag : public Poco::Net::BaseTag
/// Generates the number of the last hit shown on this page.
{
public:
DemoTag();
~DemoTag(); #ifndef USING_STENCIL_SERIALIZE
virtual void printEndTag(Poco::Net::PageRequest* req, Poco::Net::PageResponse* resp);
/// Called when the parser reaches the end tag.
///
/// @param request The page request.
/// @param response The page response.
/// @throws Exception If there was an exception.
#endif
}; #endif // DEMO_TAG_H

实现部分

#include "demo_tag.h"

DemoTag::DemoTag()
{
#if !defined(_DEBUG) || defined(USING_STENCIL_SERIALIZE)
_type = DEMO_TAG;
#endif
} DemoTag::~DemoTag()
{
} #ifndef USING_STENCIL_SERIALIZE
void DemoTag::printEndTag(Poco::Net::PageRequest* req, Poco::Net::PageResponse* resp)
{
std::string type = getParameter("type"); // 这里依据不同的type返回不同的字符串给浏览器
// 实现动态网页的效果
if (type == "chinese")
{
resp->print("你好。世界!");
}
else
resp->print("Hello World!");
}
#endif

必须将该标签类进行注冊后,WebServer才会认识

见BaseTagManager类

void BaseTagManager::registerAllTags()
{
BaseTagFactory& tagFactory = BaseTagFactory::defaultFactory();
tagFactory.registerTagClass("demo", new Instantiator<DemoTag, BaseTag>); /*
* The following will be used to create new object while loading from file
*/
#if !defined(_DEBUG) || defined(USING_STENCIL_SERIALIZE) tagFactory.registerTagClass(DEMO_TAG, new Instantiator<DemoTag, BaseTag>); #endif // NDEBUG || USING_SERIALIZE_TAG
}

至此当有来自浏览器的请求时,WebServer就能够实现动态输出网页了

前端

新建jsp文件

前端的资源所有放在root文件夹下,WebServer操作网页的根文件夹就在此。

在root目录下,我们新建一个demo的目录,再新建一个.jsp的文件。jsp扩展名用来告诉WebServer当前请求的是一个动态网页

当然你也能够使用随意其它的扩展名,假设想使用其它的扩展名,你须要改动SharedService::handle方法的例如以下部分

    if (file.exists() && file.isFile())
{
if (endsWith(newFileName, std::string(".jsp"))) // 以jsp结尾的文件表示动态网页
{
#ifdef _DEBUG
Poco::Net::Executer* root = _parser.parse(FETCH_WWWROOT, Path(newFileName).toString());
#else

加入标签

在后端代码部分,我们已经加入过标签处理类,这里须要加入前端部分,仅仅有这两边相应起来,一个真正的动态网页才干正常工作

index.jsp

<fetch:demo/>
<br>
<fetch:demo type="chinese"/>

标签说明

<fetch:demo/>。fetch没有实际作用但不能省略,可用来搜索标签。关键部分在于demo。这个是与后端的

tagFactory.registerTagClass("demo",                 new Instantiator<DemoTag, BaseTag>);

想相应的,假设你想自己新建个别的标签。全然參照demo这个做就可以

<br>,是个标准HTML标签。表示换行

<fetch:demo type="chinese"/>。跟第一行比。多了type="chinese"。这里你也能够改成其它的,但形式必须保证一致。比方你能够改成value="english"。那么相应后端的DemoTag部分中的

std::string type = getParameter("type");

则须要改成

std::string value = getParameter("value");

小结

尽管连图加上代码占领了不少篇幅,实际上仅仅须要例如以下3个步骤就可以实现一个简单的动态站点

  1. 加入Service类,并在ServiceDispatcher中依据文件名称分发
  2. 加入Tag类。并在BaseTagManager中注冊
  3. 加入jsp网页。注意与Tag类配合

假设你有精力,也能够研究一下其它代码,只是大部分时间你差点儿不用关心或改变它们。

C++写动态站点之HelloWorld!的更多相关文章

  1. <数据结构系列1>封装自己的数组——手写动态泛型数组(简化版ArrayList)

    哈哈,距离上一次写博客已经快过去半个月了,这这这,好像有点慢啊,话不多说,开始我们的手写动态泛型数组 首先是我们自己写一个自己的动态数组类,代码如下所示: public class Array< ...

  2. 写动态库时遇到了symbol lookup error问题

    之前写TLPI上的代码一直是手动进行错误处理,感觉代码冗余量很大,最后还是决定使用书上的tlph_hdr.h,顺便回顾下动态库的创建/使用. 参考很久之前的一篇博客 linux上静态库和动态库的编译和 ...

  3. CSS写动态下拉菜单 -----2017-03-27

    动态网站第一步:动态下拉菜单 关键点: overflow:hidden max-height xx:hover {} 设置当鼠标移上之后的效果 transition:   设置过度时间 cursor: ...

  4. 纯JS写动态分页样式效果

    效果图如下: html: <body> <div> <table id="btnbox"> <tbody> <tr>&l ...

  5. canvas制作柱形图/折线图/饼状图,Konva写动态饼状图

    制作饼状图 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...

  6. 今天写动态canvas柱状图小结

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  7. 用js写动态时钟 2017-03-23

    45每隔1秒变一次: 代码如下: <body onLoad="show()" >   ------------表示当页面载入时执行该事件,可以没有 <div id ...

  8. 如何使用eclipse创建JAVA项目并写一个简单的HelloWorld

    输入项目名称  点击完成(Finish) 原文地址:https://blog.csdn.net/qq_36798713/article/details/79530056

  9. [Robot Framework] 怎么写动态等待?

    举例:Robot Framwork+WhiteLibrary,等待元素可用或不可用 Wait Until Object Is Enabled Wait Until Object Is Not Enab ...

随机推荐

  1. TSOJ--方格上的路径

    题目描述: 试求 n × m 的方格图形中,从点 (0, 0) 到点 (n, m) 的最短路径数目. 输入描述: 有多组测试数据.输入的第一行为一个正整数 N,表示接下来有 N 组测试数据. 在接下来 ...

  2. 打印 Python 的一切 —— pprint & beeprint

    打印,是所有程序员从小白时期就具备的神技,遇事不决打印一下,是 DEBUG 最简单且不依赖 IDE 的方式,自定义各种日志输出,也是项目成型后必备功能.但是为了优雅的打印格式,往往需要对各种对象进行特 ...

  3. Java使用Robot完成QQ轰炸机

    效果 网上吵架吵不过别人怎么办?女朋友让你从1数到10000怎么办?想恶搞朋友怎么办?QQ轰炸机你值得拥有!(注:为了更好的学习编程,敲的练手项目,仅作学习使用) 自定义发送内容,自定义发送条数,&q ...

  4. 【01】markdown语法

    [02]段落和换行 一个 Markdown 段落是由一个或多个连续的文本行组成,它的前后要有一个以上的空行(空行的定义是显示上看起来像是空的,便会被视为空行.比方说,若某一行只包含空格和制表符,则该行 ...

  5. CentOS 下通过命令登录Mysql

    CentOS 下通过命令登录Mysql: mysql -uroot -p 按回车键后输入密码

  6. 【LeetCode】Permutations(全排列)

    这道题是LeetCode里的第46道题. 题目要求: 给定一个没有重复数字的序列,返回其所有可能的全排列. 示例: 输入: [1,2,3] 输出: [ [1,2,3], [1,3,2], [2,1,3 ...

  7. ajax dome案例

    一.首先HTML页面 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...

  8. 刷题总结——谈笑风生(主席树+dfs序的应用)

    题目: Description 设T 为一棵有根树,我们做如下的定义:• 设a和b为T 中的两个不同节点.如果a是b的祖先,那么称“a比b不知道高明到哪里去了”.• 设a 和 b 为 T 中的两个不同 ...

  9. 【loj6029】「雅礼集训 2017 Day1」市场

    题目 题意:四种操作,区间加法.区间除法(下取整).区间求最小值.区间求和. 第1.3.4个操作都是摆设,关键在于如何做区间除法. 很明显不能直接把区间的和做除法后向下取整,因为区间和可能会多凑出一个 ...

  10. AXMLPrinter2.jar反编译xml文件

    apk里的AndroidManifest.xml 为二进制文件,可通过AXMLPrinter2.jar包反编译出来 cmd命令行运行一下命令: java -jar AXMLPrinter2.jar A ...