[ Team LiB ] Previous Section Next Section

Servlet Lifecycle

A servlet goes through four phases:

  1. Loading

  2. Initialization

  3. Execution

  4. Cleanup

Servlet Loading

A servlet can be loaded at three different times:

  • When the server starts up

  • When the system administrator asks the server to load the servlet

  • When a browser tries to access the servlet

Servlet engines provide a way for you to list the servlets you want to load during startup. Although the actual loading of the servlet might take a reasonably short time, the servlet might have a costly initialization phase. By loading and initializing a servlet early, you can improve the server's response time.

For example, suppose your servlet creates several database connections during initialization and then reads and caches some data from the database. If you wait until a browser first accesses the servlet, users will experience a much longer wait than usual while the servlet performs its initialization. If you load the servlet when the server starts, the server might take a little more time to start, but users will not see any delays after everything starts. If you restart the server during periods of low usage, users might never see the slowdown from initialization.

To load a servlet, the server needs to know the classname for the servlet. Normally, the classname is the name of the servlet for which the browser asks. When a servlet is within a Java package, the servlet name contains the fully qualified Java classname. For example, a servlet class named HelloWorldServlet in the package examples would have a servlet name of examples.HelloWorldServlet.

But how does the servlet engine know that you are asking it to run a servlet? In the examples you have seen so far, the URL was http://localhost:8080/ servlet/examples.HelloWorldServlet. It's not the word "Servlet" at the end of the classname that gives the server its cue; it's the /servlet/ right before the servlet name.

About halfway through Hour 2, "JavaServer Pages Behind the Scenes," you learned about servlet mapping using a URL pattern. A typical servlet container recognizes a special servlet name called invoker. The container might not actually have a servlet named invoker; it's just a special name that the container recognizes. When configuring the container, you set up the /servlet path by mapping /servlet/* to the servlet named invoker. Then whenever the servlet engine sees a URL starting with /servlet/, it extracts the servlet name from the URL and invokes the servlet.

Getting to Know web.xml

graphics/bytheway_icon.gif

If you're using Tomcat, you may have made a change to web.xml in the conf/ directory of your Tomcat installation to enable this mapping for the examples in Hour 2. It's a great idea to take a moment to review that change and become reacquainted with that portion of web.xml.


You can also map specific URLs to specific servlets. For example, you could map the URL /HelloWorld to run the HelloWorldServlet program. You can save a little time by mapping servlet names directly, because the server doesn't have to extract a servlet name from the URL as it does when you use the invoker.

After the servlet engine knows it needs to run a servlet, it checks to see whether that servlet is already loaded in memory. If not, the servlet engine uses Java's class loading features to load the servlet into memory. After the servlet is loaded, the servlet engine initializes it and the servlet is ready to go.

Servlet Initialization

When the servlet engine initializes a servlet, it calls the servlet's init method, passing it a ServletConfig object. The init method is declared like this:


public void init(ServletConfig config)
    throws ServletException

The ServletConfig object contains initialization parameters and a ServletContext object. The initialization parameters are items that you can configure within your servlet engine that are specific to a servlet. They are set up in the deployment descriptor as part of the definition of the servlet itself. Adding an initialization parameter to the deployment descriptor is as easy as adding one or more init-param elements as children to the servlet element. Here's an example:


<servlet>
...
<init-param>
    <param-name>parameter</param-name>
    <param-value>value</param-value>
</init-param>
...
</servlet>

The following methods in ServletConfig enable you to find out what initialization parameters exist and the value of each parameter:


public java.util.Enumeration getInitParameterNames()
public String getInitParameter(String name)

Servlet initialization parameters can be used for a number of things, such as providing a path to a resource that the servlet uses.

The ServletConfig object also gives you access to the ServletContext object. ServletContext provides the servlet with a view of its runtime environment within a Web application. All of the components associated with a Web application have a view of the same context, making the context a place that is frequently used to exchange information or provide access to common services. You will frequently use the context to provide access to logs or databases. More information about ServletContext will be provided in Hour 6, "Looking Under the HoodóCore Servlet Components."

Understanding Default Context

graphics/bytheway_icon.gif

If you don't explicitly define a context, such as when you drop a JSP into the webapps/ or webapps/ROOT/ folder without any deployment descriptor, your JSP belongs to a "default" context.


Although a Web container provides initial access to ServletContext object, a servlet is responsible for keeping track of its ServletContext object. Rather than dealing with the ServletConfig object and keeping track of the ServletContext yourself, you can just make your servlet a subclass of GenericServlet or HttpServlet (which itself is a subclass of GenericServlet). These objects perform the housekeeping for you.

GenericServlet and HttpServlet provide an additional init method that doesn't take any arguments:


public void init() throws ServletException

This simplified init method is provided as a convenience for servlets that need to perform initialization. Without this init method, you would need to override the normal init method and then call super.init, like this:


public void init(ServletConfig config)
    Throws ServletException
{
    super.init(config);

    // Perform servlet-specific initialization here.
}

Override the Simplified init Method

graphics/didyouknow_icon.gif

You should override the simplified init method to perform any servlet-specific initialization.


In Case of Trouble

graphics/bytheway_icon.gif

If you are having trouble with a servlet when there is an init method, see the "Q&A" section at the end of this hour.


Servlet Execution

A servlet spends most of its time in the execution phase of its lifecycle. When a request comes in, the servlet engine invokes the servlet's service method, passing references to ServletRequest and ServletResponse objects as parameters.

Although the lifecycle's execution phase is fairly obvious, the full path of the request from browser to servlet might not be so obvious. Figure 5.1 shows the path a request takes from the browser all the way to the service method.

Figure 5.1. The Web server handles the communications with the browser while it passes data to the servlet.

graphics/05fig01.gif

The fact that the Web server handles the communications with the browser might seem insignificant, but there is one interesting point. Until recently, there hasn't been an official Secure Sockets Layer (SSL) API from Sun, yet servlets and JSPs have been able to support SSL since the Servlet API first came out. As long as your Web server supports SSL, you don't need SSL support in your Java environment. By the time requests get to your application, they don't look any different than requests that arrived using an insecure channel.

However, just because you are able to access your JSPs and servlets through SSL, don't automatically assume that you have an SSL API available for use from your Java code. If you have a servlet that must make a direct SSL request to another server somewhere, you may need to install the SSL package from Sun. As of JDK 1.4, SSL has been a part of Java 2 Standard Edition. If you use an earlier version of Java, you must install the Java Secure Sockets Extension (JSSE), available at http://java.sun.com/products/jsse.

Servlet Cleanup

When the servlet engine decides to unload a servlet (by administrator request, for performance reasons, or for system shutdown), it invokes the servlet's destroy method. The destroy method is a courtesy method to give servlets a chance to release any allocated resources that might be so precious that you can't afford to wait for garbage collection to reclaim them. For example, if your servlet allocates a large number of database connections, you should release them when the servlet is destroyed. Otherwise, it might take a while before the system reclaims them.

Although you probably don't need to worry about cleanup if the whole servlet engine is shutting down, you still need to provide for the possibility that the servlet engine will want to unload the servlet, or that you might want to manually unload it.

    [ Team LiB ] Previous Section Next Section