<!--toc--> |
|
## Введение |
|
Теперь научимся проще соединять различные URL и функции приложения. |
|
Когда клиент запрашивает определенный URL у HTTP-сервера он делится на несколько частей: `SCRIPT_NAME`, `PATH_INFO` и `QUERY_STRING`. Например |
URL `/foo/bar.php/test?x=10` разделяется на: |
|
- `SCRIPT_NAME` = `/foo/bar.php` |
- `PATH_INFO` = `/test` |
- `QUERY_STRING` = `x=10` |
|
Современные веб-приложения не разделены на несколько скриптов, а чаще пишутся одним FastCGI-приложением, запущенным на определенном URL типа "/myapp". Т.о. обычно |
URL выглядит как `/myapp/page/10`, где |
`SCRIPT_NAME` = "/myapp" остается постоянным и `PATH_INFO` = `/page/10` - изменяется в соответствии с потребностями пользователя. |
|
Т.о. соответствие между URL и функциями-членами приложения делается по совпадению регулярного выражения с `PATH_INFO` частью URL, хотя такое поведение может быть изменено использованием класса `mount_point`. |
|
## Пример |
|
Давайте перепишем наш [класс hello](/wikipp/ru/page/cppcms_1x_tut_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("/number/(\\d+)", |
&hello::number, this, 1); |
dispatcher().assign("/smile", &hello::smile, this); |
dispatcher().assign("", &hello::welcome, this); |
} |
|
В четвертой линии мы соединяем регулярное выражение `/number/(\d+)` с функцией-членом `number` экземпляра `this`, получающего `std::string` как параметр и переданное в него первое подходящее подвыражение. |
В четвертой строке мы соединяем регулярное выражение `/number/(\d+)` с функцией-членом `number` экземпляра `this`, получающего `std::string` как параметр и переданное в него первое подходящее подвыражение. |
|
В этом случае - подвыражение не пустое, содержащее цифры. |
|
В следующих двух линиях соединяются функции-члены `smile` и `welcome` с предназначенными для них URL. |
В следующих двух строках соединяются функции-члены `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> |