Implementing Request Handlers
Request handlers are the functions that handle the client request and construct a response. The servlet base classes define the request handler functions. A derived servlet implements the function or functions that handle the client request.
rwsf::HttpServlet contains default implementations of the handlers for standard HTTP requests.
For HTTP/1.1, the default implementation of most methods return the HTTP Method Not Allowed status code (405) with an appropriate message. The method doHead() first defaults to doGet() before returning status code 405.
For HTTP/1.0, requests return a Bad Request Response status code (400).
An HTTP servlet implements the functions for the methods the servlet accepts and relies on the default implementations for methods the servlet does not accept.
Table 1 – Request handlers by HTTP method
HTTP Method
rwsf::HttpServlet function
Description
DELETE
doDelete
Removes the resource from the Agent.
GET
doGet
Returns a document.
HEAD
doHead
Returns the headers for a document.
POST
doPost
Sends information to the Agent.
PUT
doPut
Uploads a file to the Agent.
TRACE
doTrace
Returns the request to the client
Each of the above functions takes a rwsf::HttpServletRequest and a rwsf::HttpServletResponse as parameters. To respond to a request, a servlet overrides the functions that correspond to the request methods the servlet accepts. For example, an HTTP servlet that accepts the HTTP GET method implements the doGet() function.
Since the HelloWorldExample servlet only responds to HTTP GET requests, the servlet only declares doGet(). The sample below shows an excerpt from the header file for the HelloWorldExample servlet:
 
// HelloWorldExample.h
 
#include <rw/rwsf/servlet/http/HttpServlet.h>
 
class HelloWorldExample : public rwsf::HttpServlet
{
 
public:
 
void doGet(rwsf::HttpServletRequest& request,
rwsf::HttpServletResponse& response);
 
};
 
The HelloWorldExample servlet does not dynamically allocate resources, so the servlet needs no init() method or destroy() method.
The implementation of the servlet simply returns an HTTP response without inspecting the request. The sample below shows the servlet implementation:
 
// HelloWorldExample.cpp
 
#include "HelloWorldExample.h"
 
// Define the servlet for the container.
 
RWSF_DEFINE_SERVLET(HelloWorldExample) // 1
 
// Implement a response to the HTTP GET method.
 
void
HelloWorldExample::doGet(rwsf::HttpServletRequest& request,
rwsf::HttpServletResponse& response)
{
// Tell the client that the response is an HTML document.
response.setContentType("text/html"); // 2
// Get a reference to the response output stream.
 
rwsf::ServletOutputStream& out = response.getOutputStream(); // 3
 
// Send a canned response to the client.
log("Hello World Example: begin"); // 4
log("Hello World Example: Starting HTML output...");
out.println("<html>");
out.println("<head>");
log("Hello World Example: Printing title...");
out.println("<title>HelloWorldExample</title>");
out.println("</head>");
out.println("<body bgcolor=\"white\">");
out.println("<h1>HelloWorldExample</h1>");
out.println("</body>");
out.println("</html>");
log("Hello World Example: Finished HTML output");
log("Hello World Example: end");
}
//1 Defines servlet HelloWorldExample for the container. The RWSF_DEFINE_SERVLET macro expands to the code the container needs to load the servlet. Each servlet must be defined for the container as described in Defining Filters, Servlets, and Listeners.
//2 Sets the Content-Type of the response to "text/html". By default, a servlet response does not contain a Content-Type header. Since this servlet returns an HTML response, the servlet sets the Content-Type accordingly.
//3 Gets a reference to the output stream for the response. The class also provides print() and println() functions that mimic the Java methods.
//4 Writes a line of the response. This servlet uses the println() function to demonstrate the similarity between a C++ servlet and a Java servlet.