问题:如何理解CPPCMS application中的dispatcher()和mapper().
#include <cppcms/application.h> #include <cppcms/applications_pool.h> #include <cppcms/service.h> #include <cppcms/http_response.h> #include <cppcms/url_dispatcher.h> #include <cppcms/url_mapper.h> #include <iostream> class hello : public cppcms::application { public: hello(cppcms::service &srv):cppcms::application(srv){ dispatcher().assign("/number/(\\d+)", &hello::number, this, 1); mapper().assign("number", "/number/{1}"); dispatcher().assign("/smile", &hello::smile, this); mapper().assign("smile", "/smile"); dispatcher().assign("", &hello::welcome, this); mapper().assign(""); mapper().root("/hello"); } void number(std::string num){ int no = atoi(num.c_str()); response().out() << "The number is " << no << "<br/>\n"; response().out() << "<a href='" << url("/") <<"'>Go back</a>"; } void smile(){ response().out() << ":-) <br/>\n"; response().out() << "<a href='" << url("/") << "'>Go back</a>"; } void welcome(){ response().out() << "<h1> Welcome to Page with links </h1>\n" "<a href='" << url("/number", 1) << "'>1</a><br>\n" "<a href='" << url("/number", 15) << "'>15</a><br>\n" "<a href='" << url("/smile") << "' >:-)</a><br>\n"; } }; int main(int argc, char **argv){ try{ cppcms::service srv(argc, argv); srv.applications_pool().mount(cppcms::applications_factory<hello>()); srv.run(); } catch(std::exception const &e){ std::cerr << e.what() << std::endl; } }
问题解决:CPPCMS web application不同于PHP脚本,而是一个整体的应用程序。因此,每当接收到REQUEST时,根据一些元变量(meta-variable)如PATH_INFO, QUERY STRING等将REQUEST分配给不同的应用程序处理句柄(成员函数)。但是QUERY STRING更适合的是PHP编写的页面, PATH_INFO更适合应用在整体化的CGI应用程序上。
基于此,DISPATCHER这个类产生了,这个类的主要功能就是将正则表达式与成员函数进行进行绑定,当然也附带传递函数调用参数。
理解了dispatcher(),那如何理解mapper()呢?其实个人认为这个mapper()的实际作用不是十分大。仔细看hello类中的成员函数,里面均调用了url(std::string)语句,这个语句在api reference文档写的十分清楚,实际就是调用mapper。通过给出一个key, 可以查询到对应的正则表达式,然后通过给定的参数构建部分PATH_INFO。
示例: url("/number", 15)
1. "/"作为mapper().root, = "/hello"
2. "number" 对应的value = "/number/{1}" /* mapper().assign("number", "/number/{1}"); */
3. 步骤2获取的value可以绑定一个参数,并且传递的参数15应放置在1的位置。
4. 所以最终形成path_info就是/hello/number/15.
当然,我说作用不大的原因是,如果CPPCMS框架不提供mapper组件时,我想大多数DEVELOPER在实际开发网站的过程中也会构建相同功能的工具吧。不过,想来cppcms的作者心是够细的,都为我们提供了如此细节的工具了。
当然mapper()也不是一点作用不起,我们知道CGI的RESPONSE消息有四种类型(document response, local redirect response, client redirect response, client redirect response with document), 其中后面的三种涉及到response header域location的重建。mapper()此时无疑帮你很大忙,因为无需再次解析path_info元变量了。
结论:
1. dispatcher()的主要功能就是通过正则表达式匹配path_info元变量,跟应用程序的句柄进行绑定。也同时让我们了解到了作为standalone cgi application与传统分配请求到不同PHP脚本的不同之处。
2. mapper()最多算一个工具类,帮助developer轻易构建script-URI.