Skip Headers

Oracle® Containers for J2EE Servlet Developer's Guide 10g Release 3 (10.1.3) B14426-01 |
| Home | Solution Area | Contents | Index

Previous | Next |

# 2 Developing Servlets

This chapter, consisting of the following sections, provides basic information for developing servlets for OC4J and the Oracle Application Server.

- Writing a Basic Servlet

- Simple Servlet Example

- Using HTML Forms and Request Parameters

- Dispatching to Other Servlets Through Includes and Forwards

- When to Use Filters for Pre-Processing and Post-Processing

- When to Use Event Listeners for Servlet Notification

For more general OC4J development information, refer to the Oracle Containers for J2EE Developer's Guide.

Note: For use during development, there is a convenience flag to direct automatic recompilation of servlet source files in a specified directory. If a source file has changed since the last request, then OC4J will, upon the next request, recompile the servlet, redeploy the Web application, and reload the servlet and any dependency classes. See the description of the `development` flag under "<orion-web-app>".

## Writing a Basic Servlet

HTTP servlets follow a standard form. They are written as public classes that extend the `javax.servlet.http.HttpServlet` class. Most servlets override either the `doGet()` method or the `doPost()` method of `HttpServlet`, to handle HTTP `GET` or `POST` requests, respectively. It may also be appropriate to override the `init()` and `destroy()` methods if special processing is required for initialization work at the time the servlet is loaded by the container, or for finalization work when the container shuts down the servlet.

The following subsections cover basic scenarios for implementing these methods, show how to set up the response, and go step-by-step through the code of a Hello World servlet:

- When to Implement Methods of the Servlet Interface

- Setting Up the Response

- Step-by-Step Through a Simple Servlet

### When to Implement Methods of the Servlet Interface

Here is a basic code template for servlet development:

    package ...;
    import ...;

    public class MyServlet extends HttpServlet {

      public void init(ServletConfig config) {
      }

      public void doGet(HttpServletRequest request, HttpServletResponse)
                        throws ServletException, IOException {
      }

      public void doPost(HttpServletRequest request, HttpServletResponse)
                        throws ServletException, IOException {
      }

      public void doPut(HttpServletRequest request, HttpServletResponse)
                        throws ServletException, IOException {
      }

      public void doDelete(HttpServletRequest request, HttpServletResponse)
                        throws ServletException, IOException {
      }

      public String getServletInfo() {
        return "Some information about the servlet.";
      }

      public void destroy() {
      }

    }

The subsections that follow discuss the scenarios for overriding any of these methods.

#### When to Override the init() Method

You can override the `init()` method to perform special actions that are required only once in the servlet lifetime, such as the following:

- Establish database connections.

- Get initialization parameters from the servlet configuration object and store the values.

- Recover persistent data that the servlet requires.

- Create expensive session objects, such as hashtables.

For example, to establish a database connection through a data source:

    public void init() throws ServletException {
       try {
          InitialContext ic = new InitialContext();  // JNDI initial context
          ds = (DataSource) ic.lookup("jdbc/OracleDS"); // JNDI lookup
          conn = ds.getConnection();  // database connection through data source
       }
       ...
    }

#### When to Override the doGet() or doPost() Method

Almost any servlet will override the `doGet()` method, to handle an HTTP `GET` request, or the `doPost()` method, to handle an HTTP `POST` request, for the bulk of its processing. `GET` and `POST` are the two HTTP methods for passing form data to the server. A detailed discussion of when to use one versus the other is beyond the scope of this manual, but the `doPost()` method may be more appropriate if security is a particular concern, given that the `GET` method places form parameters directly in the URL string, or for large sequences of data, allowing the client to send data of unlimited length to the server.

In implementing `doGet()` or `doPost()`, in addition to writing the code that generates the data to pass to the client, you will typically write code to read data from the HTTP request, set up the HTTP response, and write the response. For additional information, see "Setting Up the Response", which follows shortly, and "Using HTML Forms and Request Parameters".

"Step-by-Step Through a Simple Servlet" shows the steps for an elementary `doGet()` implementation.

#### When to Override the doPut() Method

Use this method to execute an HTTP `PUT` request, which allows a file to be written from the client to the server. The `doPut()` method must be able to handle a content header (or issue an error message if it cannot), and must leave any content headers it encounters intact.

#### When to Override the doDelete() Method

Use this method to execute an HTTP `DELETE` request, which allows a file or Web page to be removed from the server.

#### When to Override the getServletInfo() Method

Use this method to retrieve information from the servlet, such as author and version. By default, this method returns an empty string, so you must override it to provide any meaningful information.

#### When to Override the destroy() Method

This method is called by the servlet container when the servlet is about to be shut down. You can override it for any cleanup prior to shutdown that is appropriate for your servlet, such as the following:

- Update any persistent data to make sure it is current.

- Clean up any resources, such as database connections or file handles.

For example, to close the database connection that was opened in "When to Override the init() Method":

    public void destroy() {
       try {
          conn.close();
       }
       ...
    }

### Setting Up the Response

To send a response from your servlet, use the `HttpServletResponse` instance that is passed in to the servlet method you are using, typically `doGet()` or `doPost()`. The key steps are as follows:

1. Set a content type, and optionally a character encoding (MIME character set), for the response.

   Note: The OC4J default content type, if any, is reflected in the `<default-mime-type>` element of the OC4J `global-web-application.xml` (global) or `orion-web.xml` (application-level) Web application configuration file. You can set it through the deployment plan editor in the Application Server Control Console, introduced in "A Brief Overview of OC4J Administration".

2. Get a writer object (`java.io.PrintWriter`), for character data, or an output stream (`javax.servet.ServletOutputStream`), for binary data, from the response object.

3. Write the response data to the writer object or output stream.

Here is some code that shows these steps.

    public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws IOException, ServletException
    {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("<html><body><h1>Hello World</h1></body></html>");
        ...
    }

See "Key Methods of the HttpServletResponse Interface" for a summary of response methods.

Development Tip: The servlet container implicitly closes the writer object or output stream after committing the response, but it is still good programming practice to close it explicitly.

### Step-by-Step Through a Simple Servlet

This chapter shows a Hello World example that overrides the `doGet()` method. This servlet is shown in its entirety in "Simple Servlet Example", but we also go through it step-by-step here.

Initial steps in the servlet example:

1. Declare a package, as appropriate. The servlet example declares `mytest`:

       package mytest;

2. Import required Java packages, particularly the servlet packages. The following are typically required:

       import java.io.*;
       import javax.servlet.*;
       import javax.servlet.http.*;

3. Declare the servlet class, which always extends `HttpServlet` for HTTP operations:

       public class HelloWorld extends HttpServlet {
          ...
       }

4. Declare any servlet method that you want to override. The servlet methods for HTTP operations all take the same parameters (an HTTP request object and an HTTP response object) and throw the same exceptions. The servlet example overrides `doGet()`:

       public void doGet(HttpServletRequest request, HttpServletResponse response)
                         throws IOException, ServletException {
          ...
       }

Steps in the servlet example `doGet()` method:

1. Set the content type for the response object. This may not always be required, but is generally advisable:

       response.setContentType("text/html");

   Optionally, you can also specify a character encoding, such as UTF-8 in the following example:

       response.setContentType("text/html; charset=UTF-8");

2. Get a writer object from the response object:

       PrintWriter out = response.getWriter();

3. Write the data to the response object:

       out.println("<html>");
       out.println("<head>");
       out.println("<title>Hello World!</title>");
       out.println("</head>");
       out.println("<body>");
       out.println("<h1>Hi Amy!</h1>");
       out.println("</body>");
       out.println("</html>");

4. Close the output stream, which also commits the response.

       out.close();

(In this simple example, manipulating request data is not required.)

## Simple Servlet Example

This section shows the complete simple servlet example that is discussed, step-by-step, in the preceding section. This example is deployed and invoked in "Deploying and Invoking the Simple Servlet Example".

### Write the Sample Code

The following code writes "Hi Amy!" to the browser. Enter the code into a file called `HelloWorld.java`. According to the `package` statement, the `HelloWorld` class will be in package `mytest`.

    package mytest;

    import java.io.*;
    import javax.servlet.*;
    import javax.servlet.http.*;

    public class HelloWorld extends HttpServlet {

        public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws IOException, ServletException
        {
            response.setContentType("text/html");
            PrintWriter out = response.getWriter();
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Hello World!</title>");
            out.println("</head>");
            out.println("<body>");
            out.println("<h1>Hi Amy!</h1>");
            out.println("</body>");
            out.println("</html>");

            out.close();
        }
    }

### Compile the Sample Code

Compile the sample code. If you are using a JDK from Sun Microsystems, with their default compiler, accomplish this as follows, from the directory where the `.java` file is located (assuming `%` is the system prompt):

    % javac HelloWorld.java

Develo pment Tips: Add the location of the Java executables—such as the JVM, Java compiler, and JAR utility—to your system file path so you can run them from any location. For example, for the Sun Microsystems JDK 1.4.2, version 4, add `jdkroot``/j2sdk1.4.2_04/bin` to the file path, where `jdkroot` is the full path to the directory where the JDK is installed, so you can run `java`, `javac`, and `jar` from any location. How to accomplish this varies, depending on your operating system. The standard servlet classes and interfaces are provided with OC4J in a file called `servlet.jar` in the `oc4jroot``/j2ee/home/lib` directory, where `oc4jroot` is the full path to the directory where OC4J is installed. You must make `servlet.jar` available to the Java compiler. One way to accomplish this is to add `oc4jroot``/j2ee/home/lib/servlet.jar` to a system or user classpath environment variable. If you are using a Sun JDK, an alternative way to accomplish this is to copy `servlet.jar` to the JDK `jre/lib/ext` extensions directory. For example, for JDK 1.4.2, version 4, copy it to the `jdkroot``/j2sdk1.4.2_04/jre/lib/ext` directory.

## Using HTML For ms and Request Parameters

A typical servlet might ask the user to enter some information for the servlet to display or manipulate. The servlet can use HTML forms to take the information, store it in parameters of the HTTP request object, and send it to the server. You can also retrieve other information from the request object, such as the protocol, HTTP method, and request URI being used.

The following sections show some examples:

- Using an HTML Form for User Input

- Displaying Request Parameter Data Specified in User Input

- Complete Example Using a Form and Request Parameters

- Using the POST Method for URL Security

- Calling Information Methods of the Request Object

- Complete Example Retrieving Request Information

See "Key Methods of the HttpServletRequest Interface" for a summary of request methods.

### Using an HTML Form for User Input

A servlet can use an HTML form to take input from the user, then submit these data to the server as parameters of the HTTP request object. Here is an example:

    PrintWriter out = response.getWriter();
    ...
    out.print("<form action=\"");
    out.print("RequestParamExample\" ");
    out.println("method=GET>");
    out.println("Enter a new first name: ");
    out.println("<input type=text size=20 name=firstname>");
    out.println("<br>");
    out.println("Enter a new last name: ");
    out.println("<input type=text size=20 name=lastname>");
    out.println("<br>" + "<br>");
    out.println("<input type=submit>");
    out.println("</form>");

This example prompts the user to enter his or her first name, stores it in a request parameter called `firstname`, prompts for the last name, and stores it in a request parameter called `lastname`. The request object is sent to the server, where the information is processed as desired (as shown in the next section).

A significant disadvantage to using the `GET` method for this operation, however, is that the parameter names and values are appended to the servlet URL string. To prevent this, you can use the `POST` method instead, as shown in "Using the POST Method for URL Security".

### Displaying Request Parameter Data Specified in User Input

This section shows sample code that displays request parameter data that were specified by the user through an HTML form (shown in the preceding section).

    PrintWriter out = response.getWriter();
    ...
    String firstName = request.getParameter("firstname");
    String lastName = request.getParameter("lastname");
    out.println("First and last name from request:" + "<br>" + "<br>");
    if (firstName != null || lastName != null) {
        out.println("First name ");
        out.println(" = " + firstName + "<br>");
        out.println("Last name ");
        out.println(" = " + lastName + "<br>");
    } else {
        out.println("(No names entered. Please enter first and last name.)");
    }

The values of the request parameters `firstname` and `lastname` are stored in the strings `firstName` and `lastName`, then output to the user.

### Complete Exa mple Using a Form and Request Parameters

Here is the complete servlet with the code from the preceding sections. It prompts the user for first name and last name, with the information being written to the request object, then it retrieves the names from the request object and outputs them to the user. (The output code comes first, indicating "No names entered" until the user first enters some names.)

    import java.io.*;
    import javax.servlet.*;
    import javax.servlet.http.*;

    public class RequestParamExample extends HttpServlet {

        public void doGet(HttpServletRequest request,
                          HttpServletResponse response)
            throws IOException, ServletException
        {
            response.setContentType("text/html");

            PrintWriter out = response.getWriter();
            out.println("<html>");
            out.println("<body>");

            out.println("<h3>" + "My Request Parameter Example" + "</h3>");
            String firstName = request.getParameter("firstname");
            String lastName = request.getParameter("lastname");
            out.println("First and last name from request:" + "<br>" + "<br>");
            if (firstName != null || lastName != null) {
                out.println("First name ");
                out.println(" = " + firstName + "<br>");
                out.println("Last name ");
                out.println(" = " + lastName + "<br>");
            } else {
                out.println("(No names entered. Please enter first and last name.)");
            }
            out.println("<P>");
            out.print("<form action=\"");
            out.print("RequestParamExample\" ");
            out.println("method=GET>");
            out.println("Enter a new first name: ");
            out.println("<input type=text size=20 name=firstname>");
            out.println("<br>");
            out.println("Enter a new last name: ");
            out.println("<input type=text size=20 name=lastname>");
            out.println("<br>" + "<br>");
            out.println("<input type=submit>");
            out.println("</form>");

            out.println("</body>");
            out.println("</html>");
        }
    }

When the servlet first starts, it shows the following:

Description of the illustration reqpara1.gif

If you enter "Jimmy" and "Geek", then click Submit Query, it shows the following:

Description of the illustration reqpara2.gif

Development Tip: This servlet uses the HTTP `GET` method, resulting in the request parameter names and values being appended to the servlet URL. In this example, the string "`?firstname=Jimmy&lastname=Geek`" is appended. See the next section, "Using the POST Method for URL Security", for how to avoid this.

### Using the P OST Method for URL Security

The preceding example used the HTTP `GET` method, which results in request parameter names and values being appended to the servlet URL. To avoid this (typically for security considerations), you can use the `POST` method instead. In the following code, the preceding example has been modified to use the `POST` method in the form, and to use a `doPost()` method to call the `doGet()` method. Changes are highlighted in bold.

    import java.io.*;
    import javax.servlet.*;
    import javax.servlet.http.*;

    public class RequestParamExample extends HttpServlet {

        public void doGet(HttpServletRequest request,
                          HttpServletResponse response)
            throws IOException, ServletException
        {
            response.setContentType("text/html");

            PrintWriter out = response.getWriter();
            out.println("<html>");
            out.println("<body>");

            out.println("<h3>" + "My Request Parameter Example" + "</h3>");
            String firstName = request.getParameter("firstname");
            String lastName = request.getParameter("lastname");
            out.println("First and last name from request:" + "<br>" + "<br>");
            if (firstName != null || lastName != null) {
                out.println("First name ");
                out.println(" = " + firstName + "<br>");
                out.println("Last name ");
                out.println(" = " + lastName + "<br>");
            } else {
                out.println("(No names entered. Please enter first and last name.)");
            }
            out.println("<P>");
            out.print("<form action=\"");
            out.print("RequestParamExample\" ");
            out.println("method=POST>");
            out.println("Enter a new first name: ");
            out.println("<input type=text size=20 name=firstname>");
            out.println("<br>");
            out.println("Enter a new last name: ");
            out.println("<input type=text size=20 name=lastname>");
            out.println("<br>" + "<br>");
            out.println("<input type=submit>");
            out.println("</form>");

            out.println("</body>");
            out.println("</html>");
        }

        public void doPost(HttpServletRequest request,
                          HttpServletResponse response)
            throws IOException, ServletException
        {
            doGet(request, response);
        }
    }

Development Tip: There is still a `doGet()` method in this example, rather than using `doPost()` directly, because browsers use `GET` requests.

### Calling Information Methods of the Request Object

"Key Methods of the HttpServletRequest Interface" lists some methods of the request object that you can use to retrieve information about the HTTP request. Here is a code sample that calls some of the information methods of a request object and outputs the information:

    PrintWriter out = response.getWriter();
    ...
    out.println("Method:");
    out.println(request.getMethod());
    out.println("Request URI:");
    out.println(request.getRequestURI());
    out.println("Protocol:");
    out.println(request.getProtocol());

This example retrieves and displays the HTTP method (such as `GET` or `POST`), the request URI (consisting of the context path and servlet path in this example), and the protocol (such as HTTP). The next section shows a complete example.

### Complete Exa mple Retrieving Request Information

Here is a complete servlet that retrieves the HTTP method, request URI, and protocol, and outputs them in an HTML table.

    import java.io.*;
    import javax.servlet.*;
    import javax.servlet.http.*;

    public class RequestInfoExample extends HttpServlet {

        public void doGet(HttpServletRequest request,
                          HttpServletResponse response)
            throws IOException, ServletException
        {
            response.setContentType("text/html;charset=UTF-8");

            PrintWriter out = response.getWriter();
            out.println("<html>");
            out.println("<body>");

            out.println("<h3>" + "My Request Info Example" + "</h3>");
            out.println("<table border=0><tr><td>");
            out.println("Method:");
            out.println("</td><td>");
            out.println(request.getMethod());
            out.println("</td></tr><tr><td>");
            out.println("Request URI:");
            out.println("</td><td>");
            out.println(request.getRequestURI());
            out.println("</td></tr><tr><td>");
            out.println("Protocol:");
            out.println("</td><td>");
            out.println(request.getProtocol());
            out.println("</td></tr>");
            out.println("</table>");

            out.println("</body>");
            out.println("</html>");
        }
    }

This results in output such as the following:

Description of the illustration reqinfo.gif

## Dispatching to Other Servlets Through Includes and Forwards

Many servlets use other servlets in the course of their processing, either by "including" the response of another servlet or by "forwarding" the request to another servlet. The following subsections discuss these features and show examples:

- Basics of Includes and Forwards

- Why Use Includes and Forwards?

- Step-by-Step Through the Include or Forward Process

- Complete Example of a Servlet Include

Note: The target of an include or forward can be a JSP page as well as a servlet. Wherever target servlets are discussed in the following text, you can assume the same applies to target JSP pages.

### Basics of Inclu des and Forwards

In servlet terminology, a servlet include is the process by which a servlet includes the response from another servlet within its own response. Processing and response are initially handled by the originating servlet, then are turned over to the included servlet, then revert back to the originating servlet once the included servlet is finished.

With a servlet forward, processing is handled by the originating servlet up to the point of the forward call, at which point the response is reset and the target servlet takes over processing of the request. When a response is reset, any HTTP header settings and any information in the output stream are cleared from the response. After a forward, the originating servlet must not attempt to set headers or write to the response. Also note that if the response has already been committed, then a servlet cannot forward to or include another servlet.

To forward to or include another servlet, you must obtain a request dispatcher for that servlet—this is the mechanism for dispatching an HTTP request to an alternative servlet. Use either of the following servlet context methods:

- `RequestDispatcher getRequestDispatcher(String path)`

- `RequestDispatcher getNamedDispatcher(String name)`

For `getRequestDispatcher()`, input the URI path of the target servlet. For `getNamedDispatcher()`, input the name of the target servlet, according to the `<servlet-name>` element for that servlet in the `web.xml` file.

In either case, the returned object is an instance of a class that implements the `javax.servlet.RequestDispatcher` interface. (Such a class is provided by the servlet container.) The request dispatcher is a wrapper for the target servlet. In general, the duty of a request dispatcher is to serve as an intermediary in routing requests to the resource that it wraps.

A request dispatcher has the following methods to execute any includes or forwards:

- `void include(ServletRequest request, ServletResponse response)`

- `void forward(ServletRequest request, ServletResponse response)`

As you can see, you pass in the servlet request and response objects when you call these methods.

### Why Us e Includes and Forwards?

A servlet include is a convenient way to do any of the following:

- Reuse existing code without having to rewrite it.

- Include the same processing or output in multiple servlets, without having to implement the code in each individual servlet.

- Include content from a static file.

You are including the output of the target servlet in addition to the output of the originating servlet.

These points are similarly true for servlet forwards, but remember that with a forward, the output of the target servlet is instead of the output of the originating servlet, not in addition to it.

### Step-by-Step Thro ugh the Include or Forward Process

Here are basic steps to implement an include or forward:

1. Use the `getServletConfig()` method of the servlet (specified in the `javax.servlet.Servlet` interface) to retrieve a servlet configuration object.

       ServletConfig config = getServletConfig();

2. Use the `getServletContext()` method of the servlet configuration object to retrieve the servlet context object for the servlet.

       ServletContext context = config.getServletContext();

3. Use the `getRequestDispatcher()` or `getNamedDispatcher()` method of the servlet context object to retrieve a `RequestDispatcher` object. For `getRequestDispatcher()`, specify the URI path of the target servlet; for `getNamedDispatcher()`, specify the name of the target servlet, according to the relevant `<servlet-name>` element in the `web.xml` file.

       RequestDispatcher rd = context.getRequestDispatcher("path");

       RequestDispatcher rd = context.getNamedDispatcher("name");

4. Use the `include()` for `forward()` method of the request dispatcher, as appropriate, to execute the include or forward, respectively. Pass the servlet request and response objects.

       rd.include(request, response);

       rd.forward(request, response);

You can combine all four steps into a single statement, as in the following example:

    getServletConfig().getServletContext().getRequestDispatcher
                               ("path").include(request, response);

Note: Alternatively, you can retrieve a request dispatcher through the `getRequestDispatcher()` method of the request object (`HttpServletRequest` instance).

The next section shows a complete example for a servlet include.

### Complete Exam ple of a Servlet Include

This section provides a complete example of a servlet including the output of another servlet. The `RequestInfoExample` class, shown in "Complete Example Retrieving Request Information", is updated to include output from a slightly modified version of the `HelloWorld` class shown in "Simple Servlet Example".

Here is the slightly modified Hello World example whose output will be included. The class is now called `HelloIncluded` and is not in a package:

    import java.io.*;
    import javax.servlet.*;
    import javax.servlet.http.*;

    public class HelloIncluded extends HttpServlet {

        public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws IOException, ServletException
        {
            response.setContentType("text/html");
            PrintWriter out = response.getWriter();
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Hello World!</title>");
            out.println("</head>");
            out.println("<body>");
            out.println("<h1>Hi Amy!</h1>");
            out.println("</body>");
            out.println("</html>");
        }
    }

Here is the updated request information example class, now called `RequestInfoWithInclude`, that includes the output from `HelloIncluded`. Key code is highlighted in bold:

    import java.io.*;
    import javax.servlet.*;
    import javax.servlet.http.*;

    public class RequestInfoWithInclude extends HttpServlet {

        public void doGet(HttpServletRequest request,
                          HttpServletResponse response)
            throws IOException, ServletException
        {
            response.setContentType("text/html;charset=UTF-8");

            PrintWriter out = response.getWriter();
            out.println("<html>");
            out.println("<body>");

            out.println("<h3>" + "My Request Info Example" + "</h3>");
            out.println("<table border=0><tr><td>");
            out.println("Method:");
            out.println("</td><td>");
            out.println(request.getMethod());
            out.println("</td></tr><tr><td>");
            out.println("Request URI:");
            out.println("</td><td>");
            out.println(request.getRequestURI());
            out.println("</td></tr><tr><td>");
            out.println("Protocol:");
            out.println("</td><td>");
            out.println(request.getProtocol());
            out.println("</td></tr>");
            out.println("</table>");

            out.println("</body>");
            out.println("</html>");

            getServletConfig().getServletContext().getRequestDispatcher
                               ("/mypath/helloincluded").include(request, response);
        }
    }

The path `/mypath/helloincluded` is a URI consisting of the context path and servlet path. The assumption is that the application has been configured so that `HelloIncluded` can also be requested directly, as follows:

    http://host:port/mypath/helloincluded

(See Chapter 3, "Deploying and Invoking Servlets" for related information.)

You could similarly include a JSP page instead of a servlet, such as in the following example:

            getServletConfig().getServletContext().getRequestDispatcher
                               ("/mypath/hello.jsp").include(request, response);

Invoking `RequestInfoWithInclude` results in output such as the following:

Description of the illustration include.gif

## When to Use Filters for Pre-Processing and Post-Processing

Request objects and response objects are typically passed directly between the servlet container and a servlet. The servlet specification, however, allows servlet filters, which are Java programs that execute on the server and can be interposed between servlets and the servlet container to wrap and preprocess requests or to wrap and postprocess responses. A filter is invoked when there is a request for a resource that the filter has been mapped to in the servlet configuration.

Filters can effectively transform requests and responses. Use filters if you want to apply preprocessing or postprocessing for a group of servlets. (If you want to modify the request or response for just one servlet, there is no need to create a filter. You can just do what is required directly in the servlet itself.)

You can use filters in scenarios such as accessing a resource, or processing a request to that resource, prior to the request being invoked; or wrapping a request or response in a customized request object or response object, respectively. You can act on a servlet with a chain of filters in a specified order.

One example is an encryption filter. Servlets in an application may generate response data that is sensitive and should not go out over the network in clear-text form, especially when the connection has been made using a nonsecure protocol such as HTTP. A filter can encrypt the responses. (Of course, in this case the client must be able to decrypt the responses.) Other examples are filters for authentication, logging, auditing, data compression, and caching.

See Chapter 5, "Understanding and Using Servlet Filters" for details.

## When to Use Event Listeners for Servlet Notification

The servlet specification adds the capability to track key events in your Web applications through event listeners. You can implement listeners to notify your application of application events, session events, or request events. This functionality allows more efficient resource management and automated processing based on event status.

Use event listeners if there is reason for your application to be notified of any of the following.

- For the servlet context:

  - The servlet context is newly created or is about to be shut down.

  - Servlet context attributes are added, removed, or replaced.

- For a session:

  - A session is newly created or is newly invalidated or timed out.

  - Session attributes are added, removed, or replaced.

  - A session is newly active or passive.

  - An object is newly bound to or unbound from a session.

- For a request:

  - A request is being newly processed.

  - Request attributes are added, removed, or replaced.

As an example, consider a Web application comprising servlets that access a database. You can create a servlet context lifecycle event listener to manage the database connection. This event listener may function as follows:

1. The event listener is notified of application startup.

2. The application logs in to the database and stores the connection object in the servlet context.

3. Servlets use the database connection to perform SQL operations.

4. The event listener is notified of imminent application shutdown (shutdown of the Web server or removal of the application from the Web server).

5. Prior to application shutdown, the event listener closes the database connection.

An event listener class is declared in the `web.xml` deployment descriptor and invoked and registered upon application startup. When an event occurs, the servlet container calls the appropriate event listener method.

See Chapter 6, "Understanding and Using Event Listeners" for details.