First mod_servlet application - novalexei/mod_servlet GitHub Wiki

First mod_servlet application

Write

Our first application will be very simple, helloworld'ish type.

Let's create file tutorial_1.cpp and type this:

#include <iostream>
#include <servlet/servlet.h>

using namespace servlet;

class tutorial_1_servlet : public http_servlet
{
public:
    void do_get(http_request& req, http_response& resp) override
    {
        resp.set_content_type("text/html");
        std::ostream &out = resp.get_output_stream();
        out << "<!DOCTYPE html>\n"
                "<html>\n"
                "<head>\n"
                "<title>Hello servlet</title>\n"
                "</head>\n"
                "<body>\n"
                "<p>Hello, mod_servlet!</p>\n"
                "</body>\n"
                "</html>\n";
    }
};

SERVLET_EXPORT(tutorial1Servlet, tutorial_1_servlet)

That's it. Now let's go through the code and figure out what is going on there.

First we include mod_servlet servlet.h file and use its namespace:

#include <servlet/servlet.h>

using namespace servlet;

The main functional part of the mod_servlet program is a servlet. It is an object which does the main work in your web application. The mod_servlet class should inherit from http_servlet. And this is what we do next:

class tutorial_1_servlet : public http_servlet

In the class we can override several methods from the base http_servlet. But we will start from handling GET HTTP requests:

    void do_get(http_request& req, http_response& resp) override

In this method we set the response content type and get response output:

        resp.set_content_type("text/html")
        std::ostream &out = resp.get_output_stream();

And stream there the data we want to send to the client. In this case it is a basic html.

In the end of the file there is another vital part of the program:

SERVLET_EXPORT(tutorial1Servlet, tutorial_1_servlet)

This directive will export tutorial_1_servlet so that it becomes visible by mod_servlet container. It has two parameters: factory method name - name by which this servlet will be referred from mod_servlet, and the servlet class name which will be produced by the factory method. For more information on servlet export see http_servlet class reference

Build

We have the program, time to build it.

g++ -I /home/me/mod_servlet/include tutorial_1.cpp -std=c++1z -O2 -fPIC -shared -o libtutorial_1.so '-Wl,-rpath=$ORIGIN'

Couple of things to pay attention here:

  • "-I /home/me/mod_servlet/include" - include directory with mod_servlet headers.
  • '-Wl,-rpath=$ORIGIN' - this is optional, but highly recommended linker flag. It defines run-time search path for the library. It is necessary if the application library has dependencies in the same deployment directory.

Deploy

Go to webapp directory (what it is described in configuration reference) and create there new directory tutorial (this will be our web application), in that directory create WEB-INF directory and under that create lib directory. Copy libtutorial_1.so you've just built to tutorial/WEB-INF/lib. After that the directory structure of the web application will look like this:

tutorial
└── WEB-INF
    └── lib
        └── libtutorial_1.so

Configure

Now we need to configure this web application to let mod_servlet know which requests to direct to our servlet. This is done in web.xml. In our case it will be simple descriptor:

<?xml version="1.0" encoding="UTF-8"?>
<web-app>
    <servlet>
        <servlet-name>Tutorial1Servlet</servlet-name>
        <servlet-factory>libtutorial1.so:tutorial1Servlet</servlet-factory>
    </servlet>
    <servlet-mapping>
        <servlet-name>Tutorial1Servlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

Things to note here:

  • servlet-name - it is arbitrary name we choose for our servlet;
  • servlet-factory - we can see here that we instruct mod_servlet to load our servlet from libtutorial1.so library using factory method tutorial1Servlet which we declared in SERVLET_EXPORT of our program.
  • url-pattern - we set the URL which will be mapped to our application. / means that this is a default servlet which will be invoked on all URL's unless better match is found.

Copy web.xml file to tutorial/WEB-INF directory in webapps. Now directory structure of our application should look like this:

tutorial
└── WEB-INF
    ├── lib
    │   └── libtutorial_1.so
    └── web.xml

Run

We are ready to start the server. Go push the button:

/home/me/apache-httpd/2.4/bin/apachectl start

From your browser go to URL http://localhost/tutorial/ (unless you have non default port in httpd.conf specified, than use that port number in the URL) and witness the magic.

It might seam underwhelming for spoiled kids of 21 century, but what we've done here is a C++ program of under 30 lines generating web content on the server side!

Now, when we've mastered this we can generate real dynamic content in a servlet.

To The Programming Guide

⚠️ **GitHub.com Fallback** ⚠️