Servlet Development Guide : PART III Programming : Chapter 9 Creating Servlets : Implementing the Servlet Class
Implementing the Servlet Class
The SessionExample servlet supports both the HTTP GET method and the HTTP POST method. The servlet creates the same output for either method, so the doPost() function is simple -- the function simply forwards the request and response to the doGet() function.
 
// SessionExample.cpp
 
#include "SessionExample.h"
#include <rwsf/servlet/http/HttpSession.h>
#include <rwsf/core/Attribute.h>
#include <rwsf/core/DateTime.h>
#include <rwsf/core/Enumeration.h>
#include <string>
 
RWSF_DEFINE_SERVLET(SessionExample) // 1
 
void
SessionExample::doPost(rwsf::HttpServletRequest& request,
rwsf::HttpServletResponse& response)
{
doGet(request, response); // 2
}
//1 Defines servlet SessionExample for the servlet 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 Forwards the request and response to the doGet() function.
The doGet() function implements the behavior of the servlet. Because this servlet is simple, the function contains all of the servlet behavior. Further, the function freely mixes static content and dynamic content. A production application would take more care to separate the presentation and the logic, and to break the function into more manageable units.
 
void
SessionExample::doGet(rwsf::HttpServletRequest& request,
rwsf::HttpServletResponse& response)
{
response.setContentType("text/html"); // 1
rwsf::ServletOutputStream& out = response.getOutputStream(); // 2
 
//1 Sets the Content-Type of the response to "text/html".
//2 Gets a reference to the output stream of the response. The class also provides print() and println() functions that mimic the Java methods.
The next several lines produce the header of the HTML document and begin the document body.
out.println("<html>");
out.println("<body bgcolor=\"white\">");
out.println("<head>");
 
std::string title = "SessionExample";
out.println("<title>" + title + "</title>");
out.println("</head>");
out.println("<body>");
 
out.println("<h3>" + title + "</h3>");
 
The function next retrieves the session and outputs information about the session.
 
rwsf::HttpSession session = request.getSession(); // 1
out.print("SessionID ");
out.print(session.getId()); // 2
out.println("<br>");
out.print("SessionIsNew ");
out.print(session.isNew()); // 3
out.println("<br>");
 
out.println("SessionCreated ");
out.println(session.getCreationTime().asString( // 4
rwsf::DateTime::http ) + "<br>");
 
out.println("SessionsLastAccessed ");
out.println(session.getLastAccessedTime()
.asString(rwsf::DateTime::http )); // 5
out.println("<br>");
out.println("SessionRequestedID " +
request.getRequestedSessionId() + "<br>"); // 6
out.print("SessionRequestedIDValid ");
out.print(request.isRequestedSessionIdValid()); // 7
out.println("<br>");
out.print("SessionFromCookie ");
out.print(request.isRequestedSessionIdFromCookie()); // 8
out.println("<br>");
 
//1 Retrieves the session from the request. If a session for this client is active, this call returns that session. Otherwise, the servlet container creates a new session.
//2 Prints the session ID. Each session the servlet container generates has a unique ID string.
//3 Prints "true" if the session is newly created, "false" otherwise. Note that the println function follows the Java conventions for representing a boolean value.
//4 Prints the time the session was created. This line retrieves an rwsf::DateTime from the session using getCreationTime(), then calls the asString() function of the rwsf::DateTime object.
//5 Prints the time the session was last active.
//6 Prints the session ID sent by the client. This may not be the ID of the active session. For example, if the client’s previous session timed out, the client will request a session that no longer exists.
//7 Prints "true" if the client requested a valid session, "false" otherwise.
//8 Prints "true" if the client returned the session ID using a cookie, "false" if the client returned the session ID in the URL, or if the client did not return a session ID.
The servlet checks to see if the client has asked to invalidate the session. If so, the servlet invalidates the session and skips ahead to generate the forms.
 
std::string invalidate = request.getParameter("INVALIDATE"); // 1
if(invalidate != ""){
session.invalidate(); // 2
}
//1 Retrieves the value the client set for the "INVALIDATE" parameter. If the request does not contain an "INVALIDATE" parameter, getParameter() returns the empty string.
//2 Invalidates the session if the client sent an "INVALIDATE" parameter. Note that when a session is invalidated, all of the attributes in the session are destroyed.
If the client has not requested that the server invalidate the session, adds the parameter as a new attribute.
 
else {
std::string dataName = request.getParameter("dataname"); // 1
std::string dataValue = request.getParameter("datavalue");
// 2
if(dataName != "") {
rwsf::Attribute attr; // 3
attr << dataValue; // 4
session.setAttribute(dataName, attr); // 5
}
//1 Retrieves the value the client sent for the "dataname" parameter.
//2 Retrieves the value the client sent for the "datavalue" parameter.
//3 Constructs a new rwsf::Attribute. An instance of rwsf::Attribute can hold an instance of an arbitrary class, provided that the class has an assignment operator and a default constructor.
//4 Stores a copy of dataValue in attr using the insertion operator.
//5 Stores the attribute attr in the session. The session contains a collection of attributes. Each attribute is indexed by name. Note that this line replaces any previous attribute with the same name.
The loop below extracts and prints the value of each session parameter.
 
out.println("<P>"); // 1
out.println("SessionData<br>");
 
rwsf::Enumeration<std::string> names =
session.getAttributeNames(); // 2
while (names.hasMoreElements()) { // 3
std::string name = names.nextElement(); // 4
rwsf::Attribute value = session.getAttribute(name); // 5
std::string data;
value >> data; // 6
out.println(name + " = " + data + "<br>");
}
}
//1 Prints the names and values of all the attributes in the session.
//2 Retrieves the names of the parameters. rwsf::Enumeration is a simple container that mimics the Java Enumeration interface. The container provides a simple interface for iterating over the items in the container.
//3 Loops while there are more elements in the enumeration.
//4 Retrieves the next name in the enumeration.
//5 Retrieves the attribute associated with name.
//6 Extracts the string within value to data, using the extraction operator. Note that a rwsf::Attribute can only be extracted to a value of the same type as the value inserted.
The rest of the function generates the HTML forms and finishes the HTML document.
 
out.println("<P>");
out.print("<form action=\"");
out.print(response.encodeURL("SessionExample"));
out.println("\" method=POST>");
out.println("SessionDataName");
out.println("<input type=text size=20 name=dataname>");
out.println("<br>");
out.println("SessionDataValue");
out.println("<input type=text size=20 name=datavalue>");
out.println("<br>");
out.println("<input type=submit>");
out.println("</form>");
 
out.println("<P>GET based form:<br>");
out.print("<form action=\"");
out.print(response.encodeURL("SessionExample"));
out.println("\" method=GET>");
out.println("SessionDataName");
out.println("<input type=text size=20 name=dataname>");
out.println("<br>");
out.println("SessionsDataValue");
out.println("<input type=text size=20 name=datavalue>");
out.println("<br>");
out.println("<input type=submit>");
out.println("</form>");
 
out.println("<P>");
out.println("<P>Invalidate session:<br>");
out.print("<form action=\"");
out.print(response.encodeURL("SessionExample"));
out.println("\" method=POST>");
out.println("<input type=\"hidden\" name=INVALIDATE value=TRUE>");
out.println("<input type=submit value=\"Invalidate session\">");
out.println("</form>");
 
out.print("<p><a href=\"");
out.print(response.encodeURL("SessionExample"));
out.println("?dataname=foo&datavalue=bar\">URL encoded</a>");
 
out.println("</body>");
out.println("</html>");
}