Руководство: URL Mapping (v 1.x)
Введение
Теперь научимся проще соединять различные URL и функции приложения.
Когда клиент запрашивает определенный URL у HTTP-сервера он делится на несколько частей: SCRIPT_NAME, PATH_INFO и QUERY_STRING. Например
URL /foo/bar.php/test?x=10 разделяется на:
SCRIPT_NAME=/foo/bar.phpPATH_INFO=/testQUERY_STRING=x=10
Современные веб-приложения не разделены на несколько скриптов, а чаще пишутся одним FastCGI-приложением, запущенным на определенном URL типа "/myapp". Т.о. обычно
URL выглядит как /myapp/page/10, где
SCRIPT_NAME = "/myapp" остается постоянным и PATH_INFO = /page/10 - изменяется в соответствии с потребностями пользователя.
Т.о. соответствие между URL и функциями-членами приложения делается по совпадению регулярного выражения с PATH_INFO частью URL, хотя такое поведение может быть изменено использованием класса mount_point.
Пример
Давайте перепишем наш класс hello:
Т.к. мы собираемся маршрутизировать URL, добавим заголовочный файл url_dispatcher.h. Список подключаемых заголовочных файлов будет выглядеть так:
#include <cppcms/application.h> #include <cppcms/applications_pool.h> #include <cppcms/service.h> #include <cppcms/http_response.h> #include <cppcms/url_dispatcher.h> #include <iostream>
Теперь, соединим некоторые URL с функциями-членами в конструкторе:
hello(cppcms::service &srv) :
cppcms::application(srv)
{
dispatcher().assign("/number/(\\d+)",
&hello::number, this, 1);
dispatcher().assign("/smile", &hello::smile, this);
dispatcher().assign("", &hello::welcome, this);
}
В четвертой строке мы соединяем регулярное выражение /number/(\d+) с функцией-членом number экземпляра this, получающего std::string как параметр и переданное в него первое подходящее подвыражение.
В этом случае - подвыражение не пустое, содержащее цифры.
В следующих двух строках соединяются функции-члены smile и welcome с предназначенными для них URL.
Т.о., когда имя скрипта HTTP-сервера совпадет с /hello, тогда для URL
/hello- будет вызвана функцияwelcome/hello/smile- будет вызвана функцияsmile/hello/number/10- будет вызвана функцияnumberсо строкой "10" в качестве параметра.
Теперь, когда мы сообщили диспетчеру как маршрутизировать диспетчерские запросы, мы хотим, чтобы наше родительское приложение обрабатывало их. Однако, нам еще требуется определить эти функции-члены.
Замените старую функцию-член main:
virtual void main(std::string url);
. . . следующими (действиями) функциями-членами:
void number(std::string num)
{
int no = atoi(num.c_str());
response().out() << "The number is " << no << "\n";
}
void smile()
{
response().out() << ":-)";
}
void welcome()
{
response().out() <<
"<h1> Wellcome To Page with links </h1>\n"
"<a href=\"/hello/number/1\">1</a><br>\n"
"<a href=\"/hello/number/15\">15</a><br>\n"
"<a href=\"/hello/smile\">:-)</a><br>\n";
}
Не забудьте перекомпилировать проект:
c++ hello.cpp -lcppcms -o hello
А теперь самый интересный момент - запускайте приложение:
./hello -c config.js
И наберите URL: http://localhost:8080/hello
