zoukankan      html  css  js  c++  java
  • C++写动态站点之HelloWorld!

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

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


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

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

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

    静态页


    动态页



    開始使用

    IDE

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

    fetch_platformuildvc2008fetch_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语言ll作业01
    C语言寒假大作战04
    C语言寒假大作战03
    C语言寒假大作战02
    C语言寒假大作战01
    C语言I作业12—学期总结
    C语言I博客作业11
    C语言I博客作业10
    第三章预习笔记-运算方法和运算部件
    非数值数据的编码表示
  • 原文地址:https://www.cnblogs.com/gavanwanggw/p/7216977.html
Copyright © 2011-2022 走看看