The JavaTM Tutorial

| Start of Tutorial > Start of Trail > Start of Lesson | Search Feedback Form

Trail: Servlets
Lesson: Servlet Communication

## Using Other Server Resources

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

> - Have the servlet make an HTTP request. (This is a general Java programming language skill. For more information, consult resources such as the Working with URLs trail.)
> - Make a request of the resource using a `RequestDispatcher` object, if the resource is available from the server that is running the servlet.

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

> - Get a `RequestDispatcher` for the resource.
> - Forward the client request to that resource, having it reply to the user's request.
> - Include the resource's response in the servlet's output.

> ## 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:

> - `/servlet/myservlet`
> - `/servlet/tests/MyServlet.class`
> - `/myinfo.html`

> For example, this is how `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(
> >                     "/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. `BookStoreServlet` does this in the following 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, `BookStoreServlet` gets the user a session, then has the request dispatcher return the front page of the 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 `include`s 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();
> >     }

| Start of Tutorial > Start of Trail > Start of Lesson | Search Feedback Form

Copyright 1995-2001 Sun Microsystems, Inc. All rights reserved.