More About GenericServlet
Listing 12.2 inherits from javax.Servlet.GenericServlet. This class
is just what its name implies: a Servlet class that is not specific to any
protocol. The HttpServlet class is more common for web programming
because it is specific to the HTTP protocol; however, GenericServlet is
HttpServlet's superclass, and its methods are important to know.
Table 12.1 has a summary of Java method signatures for GenericServlet
and examples of how a Jython subclass of GenericServlet would use those
methods. These are not all the methodsjust those easily used from Jython.
Table 12.1 lists methods in two categories:
Methods overridden in the Jython subclass, noted by the def
statements.
Superclass methods invoked from the Jython subclass, noted by qualifying
the method with self.
Table 12.1 GenericServlet Methods
|
Java Signature
|
Usage in Jython Subclass
|
|
Methods You Subclass:
|
|
public void init(ServletConfig config) throws ServletException;
|
def init(self, config):
|
|
public void destroy();
|
def destroy(self):
|
|
public abstract void service(ServletRequest request, ServletResponse
response) throws Servletexception, IOException;
|
def service(self, request, response):
|
|
public String getServletInfo();
|
def getServletInfo(self): return "Info string"
|
|
Methods You Use with the self.Method Syntax:
|
|
public void log(String message);
|
self.log("message")
|
|
public ServletConfig getServletConfig();
|
config = self.getServletConfig()
|
|
public java.util.enumeration getInitParameterNames();
|
nameList = self.getInitParameterNames()
|
|
public String getInitParameter(String name)
|
param = self.getInitParameter("paramName")
|
|
public ServletContext getServletContext()
|
context = self.getServletContext
|
You have already seen an example of overloading the public
abstract void service() method in Listing 12.2. The other methods available
for overloading get attention in the following hit counter Servlet.
A hit counter Servlet is almost as obligatory as a Hello
World application in the pedagogy of programming. Here it is in the name of
tradition. The hitCounter Servlet (see Listing 12.3) shows the use of
the init, service, and destroy methods. A discussion
of each of these methods appears following the listing.
Listing 12.3 HitCounter Servlet
# filename: HitCounter.py
from javax import servlet
from time import time, ctime
import os
class HitCounter(servlet.GenericServlet):
def init(self, cfg=None):
if cfg:
servlet.GenericServlet.init(self, cfg)
else:
servlet.GenericServlet.init(self)
# Construct a path + filename to file storing hit data
contextRoot = self.servletContext.getRealPath(".")
self.file = os.path.join(contextRoot, "counterdata.txt")
if os.path.exists(self.file):
lastCount = open(self.file, "r").read()
try:
# within 'try' just in case the file is empty
self.totalHits = int(lastCount)
except:
self.totalHits = 0
else:
self.totalHits = 0
def service(self, req, res):
res.setContentType("text/html")
toClient = res.getWriter()
toClient.println("<html><body>")
toClient.println("Total Hits: %i<br>" % (self.totalHits,))
self.totalHits += 1
toClient.println("</body></html>")
def destroy(self):
f = open(self.file, "w")
f.write(str(self.totalHits))
f.close()
Place the HitCounter.py in the context's classes
directory (%TOMCAT_HOME%\webapps\jython\WEB-INF\classes), and compile
it with jythonc from within the same directory.
jythonc w . deep HitCounter.py
Test the HitCounter Servlet by pointing you browser to
http://localhost:8080/jython/servlet/HitCounter.
You should see the message "Total Hits: 0" The first time you visit
this URL. Each subsequent hit increments the count. If you shut down Tomcat with
%TOMCAT_HOME%\bin\shutdown.bat ($TOMCAT_HOME/bin/shutdown.sh
for bash) and restart Tomcat, the hit count should continue at its last
number.
The three methods init, service, and destroy are
essential to Servlets, and each one matches a stage of a Servlet's life
cycle. A Servlet is first loaded and initialized: the init() method. A
Servlet then handles client requests: the service() method. A Servlet
handles requests until it is unloaded or removed from the Servlet
container(): the destroy method.
init(ServletConfig) Method
The init() method is called at Servlet startup, and only called that
one time. This makes it useful for time-intensive tasks such as setting up
database connections, compiling regular expressions or loading ancillary files.
The purpose of including an init() method in Listing 12.3 is to
establish the file that stores the hit information, and to set the counter to
the last stored integer in that file. This implementation ensures that the hit
counter is not reset to 0 unless the Servlet is restarted and the
counter.txt file is missing.
The 2.2 version of the Servlet API has two init() methods: a
parameterless version and one that accepts an instance of the
ServletConfig class. Listing 17.3 uses the variable cfg for
this object. It's important to remember that when Jython overrides a Java
method, it overrides all methods with that name. This means that defining an
init() method in a Jython Servlet overrides both the parameterless
init() and the init(ServletConfig cfg) methods. Listing 17.3
handles the functionality of both methods by specifying a default argument of
None for the cfg variable, then testing for None to
determine if that cfg variable should be used when calling the
superclass's init() method.
service(ServletRequest, ServletResponse) Method
This is the method called in response to each client request. A Servlet must
define this method because it is abstract in GenericServlet. The
arguments passed to this method are the ServletRequest and the
ServletResponse objects. ServletRequest contains client
information sent in the request to the server such as the request headers,
request method, and request parameters. ServletResponse is used for
sending the response stream in the appropriate mime-encoded format back to the
client.
destroy() Method
This is called when shutting down or unloading a Servlet. Cleanup code goes
here, including closing database connections, flushing and closing files, and so
on.
The destroy method in Listing 12.3 writes the hit counter value to a
file so that the information is not lost when the Servlet is unloaded. This
isn't the best means of persistence, however. The hit count value only gets
stored if the server is shutdown politely. If the Servlet container is not
shutdown properly, the destroy method may not be called. When you are using
Tomcat, you usually start and stop the server with the startup and shutdown
shell scripts. These are the polite and proper ways to start and stop Tomcat;
however, if you choose to stop Tomcat with an impolite "Ctrl+C", the
proper shutdown sequence is skipped. Additionally, an error that unexpectedly
terminated Tomcat causes the same results, and the hit count would be lost.
Higher quality persistence would require that the data be stored in a way that
the assignment and commit are in a transaction framework.
New on the Java Boutique:
New Review:
Time Management Made Easy with the Quartz Enterprise Job Scheduler
Why not just use the Java timer API? This open source scheduling
API boasts simplicity, ease-of-integration, a well-rounded feature
set, and it's free!
New Applet:
Reverse Complement
Reverse Complement is a simple applet that converts DNA or RNA
sequences into three useful formats.
Elsewhere on internet.com:
WebDeveloper Java
Lots of Java information on webdeveloper.com
WDVL Java
Thorough Java resource at the Web Developer's Virtual Library.
ScriptSearch Java
Hundreds of free Java code files to download.
jGuru: Your View of the Java Universe
Customizable portal with online training, FAQs, regular news updates, and tutorials.
|