理解cppcms中的dispatcher和mapper

问题:如何理解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.

你可能感兴趣的:(dispatcher)