Main  /  Edit version 3  /  Edit version 4  /   /  Users Area

Difference "URL Dispatching and Mapping" ver. 3 versus ver. 4

Titles:

Version 3Version 4
Tutorial: URL Mapping (v 1.x)URL Dispatching and Mapping

Content:

<!--toc-->
## Introduction
Now we would learn how to connect between different URLs and the application functions easily.
When client requests specific URL from the HTTP server
it divides it into several parts: `SCRIPT_NAME`, `PATH_INFO` and `QUERY_STRING`. For example
it divides it into several parts (CGI variables): `SCRIPT_NAME`, `PATH_INFO` and `QUERY_STRING`. For example
URL `/foo/bar.php/test?x=10` is separated into:
- `SCRIPT_NAME` = `/foo/bar.php`
- `PATH_INFO` = `/test`
- `QUERY_STRING` = `x=10`
Today web applications are not distributed into several
scripts but rather written using a single FastCGI application that runs on specific url like "/myapp", So
CppCMS web applications are not distributed into several
scripts but rather written using a single FastCGI application that runs on specific "script" url like "/myapp", So
generally URLs would look like `/myapp/page/10`, when
`SCRIPT_NAME` = "/myapp" remains constant and `PATH_INFO` = `/page/10` is changed according to user's needs.
So the mapping between URL and applications member functions
are done by matching a regular expression against `PATH_INFO` part of URL, even thou this behavior can be changed by using `mount_point` class.
are done by matching a regular expression against `PATH_INFO` part of URL, even though this behavior can be changed by using `mount_point` class.
## Example
This job is done by `cppcms::url_dispatcher` class.
The opposite of the dispatching is "mapping" when the names of the application parts are converted to a URL 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` header file. Your include list should look like:
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/applications_pool.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);
dispatcher().assign("/smile", &hello::smile, this);
dispatcher().assign("", &hello::welcome, this);
}
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 1st captured subexpression is passed to it.
and 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 nonempty string that contains digits.
In next two lines we connect member functions `smile` and `welcome` to the appropriate URLs.
In the 5th line we create a name for this part called
"number" and we provide a URL formatting pattern `/number/{1}` - the opposite of regular expression where `{1}` is a placeholder for the first parameter for formatting the appropriate URL.
So when the script name the HTTP server matches against is
`/hello` then for URLs
In next lines 7-8 connect member function `smile`
to its URL and create a mapping. Because this URL
does not have any parameters it does not have
any placeholders.
The the line 10 we connect the empty URL to the
`welcome` member function and in the line 11 we define default empty mapping patter for the URL. Note, because
we pass only one parameter to the `assign()` function,
we define the default URL for the application.
In the line 13 we define the "root" of the all URLs for the
`url_mapper` class, in our case it should be identical the
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.
We want our parent application class to handle dispatching the requests now that we have informed the dispatcher how to route them; however, we still need to define those member functions.
Replace the old `main` member function:
Because the "routing table" between the URL and the
application member functions is done we don't need
to override the `cppcms::application::main` member
function as it does the all dispatching for us.
virtual void main(std::string url);
### Actions
. . . with the following (action) member functions:
The "number" member function.
void number(std::string num)
{
int no = atoi(num.c_str());
response().out() << "The number is " << no << "\n";
response().out() << "The number is " << no << "<br/>\n";
response().out() << "<a href='" << url("/") << "'>Go back</a>";
}
Note, we using `url("/")` as 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 the twe `welcome` member functions
In the same way we create the `smile` member function:
void smile()
{
response().out() << ":-)";
response().out() << ":-) <br/>\n";
response().out() << "<a href='" << url("/") << "'>Go back</a>";
}
Now we would write out `welcome` action:
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";
"<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";
}
Don't forget to recompile it:
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.
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