The JavaTM Tutorial
Previous Page Lesson Contents Next Page Start of Tutorial > Start of Trail > Start of Lesson Search

Trail: Servlets
Lesson: Servlet Communication

Using Other Server Resources (JSDK 2.1)

To have your servlet access another resource such as another servlet, a JSP page, or a CGI script, you can either:

This lesson addresses the second option, showing you how to:

Getting a RequestDispatcher Object

To gain access to a RequestDispatcher object, use the ServletContext object's getRequestDispatcher method. This method takes the requested resource's URL as an argument. The format of this argument is a slash ("/") followed by one or more slash-separated directory names, and ending with the name of the resource. The following are examples of valid URLs:
 

For example, when the BookStoreServlet gets a RequestDispatcher object for the main page of Duke's Bookstore:

public class BookStoreServlet extends HttpServlet {

    public void service (HttpServletRequest request,
                         HttpServletResponse response)
        throws ServletException, IOException
    {
        // Get the dispatcher; it gets the main page to the user
        RequestDispatcher dispatcher =
            getServletContext().getRequestDispatcher(
                "/examples/applications/bookstore/bookstore.html");
        ...
    }
}

The URL must be for a resource currently available on the server that is running the servlet. If the resource is not available, or if the server has not implemented a RequestDispatcher object for that type of resource, this method will return null. The servlet should be prepared to deal with this condition. The BookStoreServlet does this in the following simple way:

public class BookStoreServlet extends HttpServlet {

    public void service (HttpServletRequest request,
                         HttpServletResponse response)
        throws ServletException, IOException
    {
        // Get the dispatcher; it gets the main page to the user
        RequestDispatcher dispatcher = ...;

        if (dispatcher == null) {
            // No dispatcher means the html file can not be delivered
            response.sendError(response.SC_NO_CONTENT);
	} ...
    }
}

Forwarding a Request

Once you have the RequestDispatcher object, you can give its associated resource the responsibility for responding to the client request. Forwarding is useful, for example, when the servlet processes the request but the response is generic so it can be handed off to another resource. A servlet might, for example, handle a the credit card information when a user places an order, then pass the client request off to an order that returns a "Thank you" page. In the Duke's Bookstore example, the BookStoreServlet gets the user a session, then has the request dispatcher return the front page of Duke's Bookstore:

public class BookStoreServlet extends HttpServlet {

    public void service (HttpServletRequest request,
                         HttpServletResponse response)
        throws ServletException, IOException
    {
        ...
            // Get or start a new session for this user
            HttpSession session = request.getSession();
            // Send the user the bookstore's opening page
            dispatcher.forward(request, response);
	...
    }
}

Remember that the forward method should be used to give another resource the responsibility of replying to the user. If you have already accessed a ServletOutputStream or PrintWriter object, you cannot use this method; it throws an IllegalStateException.

If you have already started replying to the user by accessing the PrintWriter or ServletOutputStream, you must use the include method instead.

Including a Request

The include method of the RequestDispatcher interface provides the calling servlet the ability to respond to the client, but to use the RequestDispatcher object's associated resource for part of the reply.

Because the servlet calls the RequestDispatcher.include method is also expected to respond to the client, the servlet can use the PrintWriter and ServletOutputStream objects before and after it calls the include method. You must keep in mind, however, that the called resource cannot set headers in the client response. If the resource tries to set headers, the headers are not guaranteed to be set.

The following example shows what the ReceiptServlet might look like if, instead of merely thanking the user for the order, it also included an order-summary. The example, which you should consider pseudo-code, thanks the user for the order, then includes the output of an order summary servlet in the output:

public class ReceiptServlet extends HttpServlet { 

public void doPut(HttpServletRequest req,
                    HttpServletResponse res)
    throws ServletException, IOException
{
    // Process a customer's order
    ...
    // Thank the customer for the order
    res.setContentType("text/html");
    PrintWriter toClient = res.getWriter();
    ...
    toClient.println("Thank you for your order!");

    // Get the request-dispatcher, to send an order-summary to the client
    RequestDispatcher summary =
      getServletContext().getRequestDispatcher(
          "/OrderSummary");

    // Have the servlet summarize the order; skip summary on error.
    if (summary != null)
        try {
            summary.include(req, res);
        } catch (IOException e) {
        } catch (ServletException e) {
        }

    toClient.println("Come back soon!");
    toClient.println("</html>");
    toClient.close();
}

Previous Page Lesson Contents Next Page Start of Tutorial > Start of Trail > Start of Lesson Search