[ Team LiB ] Previous Section Next Section

Servlet Life Cycle

In this section, we look at the life cycle of the servlet from initialization to destruction and the functions that control it. The core abstract interface of the Servlet API, Servlet, defines the life cycle of a servlet using the init(), service(), and destroy() methods. All servlets are direct or indirect implementations of the Servlet interface, either through the protocol-independent GenericServlet interface or the HTTP protocol-based HttpServlet.

Configuration, Loading, and Instantiation

As a servlet container implementing the Sun Servlet specification, WebLogic Server is responsible for loading and instantiating the configured servlets at the user-configured time. The server provides the capability of loading the servlets at server startup time or at the first invocation of a request targeted at the servlet. The optional load-on-startup tag of the servlet element defined in the Web application deployment descriptor (web.xml) controls the loading sequence of servlets and also determines whether the servlet is to be loaded at startup time. The value of this optional element should be a positive integer indicating the order in which the servlet should be loaded starting with the lowest number. WebLogic Server determines the startup sequence if the value is not a positive integer or is intentionally left blank.

Initialization

Initialization of the servlet object follows the instantiation process defined earlier. WebLogic Server initializes the servlet instance using the init() method defined in the Servlet interface. This method is used for one-time initialization operations such as reading configuration parameters from a file, opening connections to expensive resources such as databases and legacy systems, and so on.

The init method comes in two flavors. The first version of the init method takes no arguments. This version is used when the servlet has no configuration parameters to read to initialize some basic settings to be used later. The following code snippet gives an example of such an init method. The servlet init method opens a configuration file and assigns it to a static variable, which may be used elsewhere in the servlet.


public void init() {

      try {
          configFile = new File("c:\\wlsunleashed\\config\\appconfig.xml");
          ....
       }
       catch (Exception ex) {
              System.out.println("init() failed:" + ex);
        }
}

The second version of the init method takes the ServletConfig object as an argument. The ServletConfig object is a configuration object that has the following functions:

  • Aids servlets in accessing name-value configuration parameters defined in the Web application deployment configuration

  • Provides access to the ServletContext object, which represents the servlet's runtime environment

The servlet can use the initialization parameters to define database connection properties, log file locations, and much more. The init function in the earlier example can be changed not to hard-code the name and location of the configuration file and instead read the same from the Web deployment descriptor. That version of the init method looks like this:


public void init(ServletConfig config) {
      super.init(config);
      // Initialize the class level config variable
      // Can be used later in the processing
      myConfig = config;
      String filename = getInitParameter("configFile");
      try {
          configFile = new File(filename);
          ....
      }
      catch (Exception ex) {
             System.out.println("init() failed:" + ex);
        }
}

The super.init is the first call that's made in the init method to ensure that the ServletConfig is registered before it's used. The initialization parameters are defined in the web.xml file as part of the servlet element. The initialization parameters for the earlier code snippet looks like the following:


<servlet>
    <servlet-name>InitServlet</servlet-name>
    <servlet-class>wlsunleashed.servlets..InitServlet</servlet-class>
    <init-param>
      <param-name>configFile</param-name>
      <param-value d:\\wlsunleashed\\config\\appconfig.xml </param-value>
    </init-param>
  </servlet>

The <init-param> tag defines the parameters that are read using the ServletConfig object passed in the init method. This tag is one of the many ways to initialize an application in the J2EE world. The tag is tied to a particular servlet as defined in the deployment descriptor, so the scope of this tag is limited to the configured servlet.

NOTE

Initialization parameters can be set up in a number of ways depending on the application scope requirements. The init-param is for a single servlet, whereas context-param is for all servlets and env-entry is for all components of the Web application. Additionally, custom properties files can be used to define parameters and read in the application. Also, if the parameters are to be shared to all server instances across the network, JNDI provides a viable option.


At this point, there's one outstanding question that must still be answered. The question that often comes up is, "Should I put my initialization code in init() or the constructor?"

Let's look at a reason why you would use the init() method rather than a constructor. The constructor is called sometime before the init() method is invoked. At the time the constructor is invoked, the container does not know about the initialization parameters that the developer is expecting as part of the servlet instance creation step. The container has to assume that the developer has added the no-argument default constructor that can be used for creating the default instance of the servlet. Any initialization parameters supplied to the servlet using the deployment descriptor will not be available in the constructor using ServletContext. In this case, other mechanisms may be used as noted earlier. This might not be construed as a major limitation, but it is a means of keeping the API and implementation as simple as possible.

Processing

All requests received by the servlet are processed by the servlet's service method using a new thread for every client request. The HttpServlet interface, a subinterface of the Servlet interface, is the most commonly used servlet interface for processing HTTP-based requests. The HttpServlet interface adds specialized methods that are automatically invoked by the service method. Table 14.2 summarizes the list of HTTP request-handling methods defined by this subinterface of Servlet.

Table 14.2. HTTPServlet Service Methods

Method Name

Request Type

Description

doDelete

HTTP DELETE requests

Removes a document or Web page from the server

doGet

HTTP GET requests

Handles client service requests (via the service method)

doHead

HTTP HEAD requests

Specialized GET request in which the client requires only the response headers

doOptions

HTTP OPTIONS requests

Determines the HTTP methods that are supported by the WebLogic Server

doPost

HTTP POST requests

Handles client service requests; similar to doGet

doPut

HTTP PUT requests

Used to execute FTP-type operations by allowing clients to place files on the server

doTrace

HTTP Trace requests

Useful in debugging

Unloading the Servlet

When the servlet is unloaded from the Web container, the servlet engine invokes the destroy method. This is the last method in the servlet life cycle. The destroy method can be used for closing out connections to resources such as databases and legacy applications, freeing up any other resources that can be connected and/or instantiated in the init method or later during the life of the servlet.

The destroy method does not take an argument. The destroy method for the simple servlet referenced earlier can be used to free the context that was initialized in the init method:


public void destroy() {
  // configFile is the configuration file handler
  // initialized in the init method
   configFile = null;
}

Figure 14.1 describes the typical life cycle of the servlet using the simple servlet mentioned earlier.

Figure 14.1. Servlet life cycle.

graphics/14fig01.gif

The programmer has to consider one important point when using the destroy method. This method should not be counted as the only mechanism for clean up, saving session data, and so forth because the container controls only this method invocation. Valuable data could be lost if there were a crash of the system or any other fatal error in which the destroy method may not be invoked by the container. So, it's prudent to store important data at the earliest possible opportunity and not wait for the destroy method.

    [ Team LiB ] Previous Section Next Section