The Anatomy of a Servlet
As you just saw in the HelloWorldServlet, a servlet is a Java class that implements a few important methods. You can choose to implement these methods yourself or create a subclass of an existing servlet class that already implements them. The Servlet interface defines the methods that are required for a Java class to become a servlet. The interface definition is shown in Listing 3.2.
Listing 3.2 The Definition of the Servlet Interface
package javax.servlet; public interface Servlet { public void destroy(); public ServletConfig getServletConfig(); public String getServletInfo(); public void init(ServletConfig config) throws ServletException; public void service(ServletRequest request, ServletResponse response) throws ServletException, java.io.IOException; }
Most of the time, you will create a servlet by subclassing either GenericServlet or HttpServlet. Both of these classes implement the Servlet interface, but they provide a few handy features that make them preferable to implementing the Servlet interface yourself.
The service Method
The heart of any servlet is the service method. As you just learned, the servlet engine calls the service method to handle each request from a browser, passing in an object containing both information about the request that invoked the servlet and information about sending back a response. The service method is the only method that a servlet is actually required to implement. The service method is declared this way:
public void service(ServletRequest request, ServletResponse response) throws java.io.IOException
The init Method
Many times, a servlet needs to perform some initialization one time before it begins to handle requests. The init method in a servlet is called just after the servlet is first loaded, but before it begins to handle requests. Listing 3.3 shows a simple init method that initializes a database connection.
Listing 3.3 init Method from JDBCServlet.java
protected Connection conn; public void init() { try { // Make sure the JdbcOdbcDriver class is loaded Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); // Try to connect to a database via ODBC conn = DriverManager.getConnection( "jdbc:odbc:usingjsp"); } catch (Exception exc) { // If there's an error, use the servlet logging API getServletContext().log( "Error making JDBC connection: ", exc); } }
Notice that the init method in Listing 3.3 does not take a parameter like the init method in the Servlet interface. One of the convenient features of the GenericServlet and HttpServlet classes is that they have an alternate version of init that doesn't take any parameters. In case you're wondering why it even matters, the init method in the Servlet interface takes a ServletConfig object as a parameter. The servlet is then responsible for keeping track of the ServletConfig object. The GenericServlet and HttpServlet classes perform this housekeeping chore and then provide the parameter-less init method for you to do any servlet-specific initialization.
CAUTION
If you override the init(ServletConfig config) method of GenericServlet or HttpServlet, make sure you call super.init(config) as the first statement in your init method so that the housekeeping will still be performed.
The destroy Method
Sometimes, the servlet engine decides that it doesn't need to keep your servlet loaded anymore. This could happen automatically, or as the result of you deactivating the servlet from an administration tool. Before the servlet engine unloads your servlet, it calls the destroy method to enable the servlet to perform any necessary cleanup. The cleanup usually involves closing database connections, open files, and network connections. Listing 3.4 shows the destroy method that is a companion to the init method in Listing 3.3.
Listing 3.4 destroy Method from JDBCServlet.java
public void destroy() { try { // Only try to close the connection if it's non-null if (conn != null) { conn.close(); } } catch (SQLException exc) { // If there's an error, use the servlet logging API getServletContext().log( "Error closing JDBC connection: ", exc); } }
The getServletInfo and getServletConfig Methods
If you are subclassing GenericServlet or HttpServlet, you probably won't need to override the getServletInfo or getServletConfig methods. The Servlet API documentation recommends that you return information such as the author, version, and copyright from the getServletInfo method. Although there is no specific format for the string returned by the method, you should return only plain text, without any HTML or XML tags embedded within it.
The getServletConfig method returns the ServletConfig object that was passed to the servlet in the init method. Unless you are keeping track of the config object yourself, your best bet is to leave this method alone and let the superclass handle it.