C++写动态网站之HelloWorld!

来源:互联网 发布:历史地理 书籍 知乎 编辑:程序博客网 时间:2024/06/15 03:16

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

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


简单的说,动态网站就是可以动态变更的网站,动态变化的内容通常来自后端数据库,如下省略万字(动态网站

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

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

静态页


动态页



开始使用

IDE

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

fetch_platform\build\vc2008\fetch_platform.sln,按如下图所示配置


网站端口

网站程序的入口在文件HTTPFormServer.cpp,下面是网站的端口,通常为80端口,为了避免可能的端口冲突,这里使用8020,网站程序运行起来可以使用http://localhost:8020/访问

当然如果你电脑上的80端口没有被其他程序占用,可以简单的使用http://localhost/进行访问

            unsigned short port = 8020;if (args.size() > 0) // change default portport = (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_SERIALIZEvoid 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类配合

如果你有精力,也可以研究一下其他代码,不过大部分时间你几乎不用关心或改变它们

1 0
原创粉丝点击