Main  /  Edit version 9  /  Edit version 10  /   /  Users Area

Difference "URL Dispatching and Mapping" ver. 9 versus ver. 10

Content:

<!--toc-->
## Introduction
Now we will learn how to connect different URLs to their associated functions easily.
When a client requests a specific URL from the HTTP server,
it divides it into several parts (CGI variables): `SCRIPT_NAME`, `PATH_INFO` and `QUERY_STRING`. For example
the URL `/foo/bar.php/test?x=10` is separated into:
- `SCRIPT_NAME` = `/foo/bar.php`
- `PATH_INFO` = `/test`
- `QUERY_STRING` = `x=10`
CppCMS web applications are not distributed into several
scripts, but rather they're written using a single FastCGI application that runs on a specific "script" url, like "/myapp". So generally URLs would look like `/myapp/page/10`, where
`SCRIPT_NAME` = "/myapp" would remain constant and `PATH_INFO` = `/page/10` is changed according to the user's needs.
So the mapping between the URL and the application's member functions is done by matching a regular expression against the `PATH_INFO` part of the URL, even though this behaviour can be changed by using the `mount_point` class.
This job is done by the `cppcms::url_dispatcher` class.
The opposite of the dispatching is "mapping" where the names of the application parts are converted to a URLs that can be given to the user.
## Code
### Mapping
Lets rewrite our [hello class](/wikipp/en/page/cppcms_1x_tut_hello):
Since we will be routing URLs, let's include the `url_dispatcher.h` and `url_mapper.h` header file. Your include list should look like:
#include <cppcms/application.h>
#include <cppcms/service.h>
#include <cppcms/http_response.h>
#include <cppcms/url_dispatcher.h>
#include <cppcms/url_mapper.h>
#include <cppcms/applications_pool.h>
#include <iostream>
#include <stdlib.h>
Now in our constructor, let's map some URLs to member functions:
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");
}
In the fourth line we connect the regular expression `/number/(\d+)` to the member function `number` of `this`
instance that receives `std::string` as parameter,
and the 1st captured subexpression is passed to it (note the parameter 1 that represents the 1st subexpression as a parameter)
In this case the subexpression is a nonempty string that contains digits.
In the 5th line we create a name for this part called
"number" and we provide an URL formatting pattern of `/number/{1}` - the opposite of the regular expression where `{1}` is a placeholder for the first parameter for formatting the appropriate URL.
In the lines 7-8 we connect the member function `smile`
to its URL and create a mapping. Because this URL
does not have any parameters it does not have
any placeholders.
On line 10 we connect the empty URL to the
`welcome` member function, and on line 11 we define the default empty mapping pattern for the URL. Note, because
we pass only one parameter to the `assign()` function,
we define the default URL for the application.
On line 13 we define the "root" of all the URLs for the
`url_mapper` class, in our case it should be identical to
the `SCRIPT_NAME` CGI variable.
### Description
So when the web server receives requests that match
a script name `/hello` it forwards them to the application:
- `/hello` - `welcome` function would be called
- `/hello/smile` - `smile` function would be called
- `/hello/number/10` - `number` function would be called and receive a string "10" as parameter.
Because the "routing table" between the URL and the
application's member functions is done, we don't need
to override the `cppcms::application::main` member
function as it does all the dispatching for us.
### Actions
The "number" member function.
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>";
}
Note, we're using `url("/")` as an abstract URL for the default application entry point - the `/` part describes the root application (our single application) and the fact that nothing follows it shows that the default URL should be
given - the mapping to the `welcome` member function.
In the same way we create the `smile` member function:
void smile()
{
response().out() << ":-) <br/>\n";
response().out() << "<a href='" << url("/") << "'>Go back</a>";
}
Now we would write out `welcome` action:
Now we write out the `welcome` action:
void welcome()
{
response().out() <<
"<h1> Wellcome To Page with links </h1>\n"
"<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";
}
Note, we show three URLs to the different application
parts: "number" - and we would pass a parameter `1` to the `cppcms::application::url` function that would be rendered instead of the placeholder `{1}`, we do the same for
number 15 and pass a URL to "smile" part without parameters.
parts: "number" - and we pass a parameter `1` to the `cppcms::application::url` function that will be rendered instead of the placeholder `{1}`, we do the same for
number 15 and pass an URL to "smile" without parameters.
Lets describe in the example the actions that are taken for when we call `url("/number",15)`:
- First for "/" we go to the topmost application, in out case to `this` one.
- Next we match "number" against the known pattern "number" that was mapped to `"/number/{1}"`.
- We fetch the pattern and use the parameter that is passed to `url` function and convert: `/number/{1}` to `/number/15`.
- Finally we perpend the root URL path "/hello" and get our final URL `/hello/number/15`.
Note: the parameters to `url` family of functions can be anything that can be written to `std::ostream` - i.e. any object that defined operator `<<` with standard C++ streams.
## Running The Example
Recompile it:
c++ hello.cpp -lcppcms -o hello
And now for the exciting part, start your application:
./hello -c config.js
And hit the URL: <http://localhost:8080/hello>

About

CppCMS is a web development framework for performance demanding applications.

Support This Project

SourceForge.net Logo

Поддержать проект

CppCMS needs You


Navigation

Main Page


Valid CSS | Valid XHTML 1.0