Start of Tutorial > Start of Trail > Start of Lesson | Search |
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 theServletContext
object'sgetRequestDispatcher
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, 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 returnnull
. 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 aServletOutputStream
orPrintWriter
object, you cannot use this method; it throws anIllegalStateException
.If you have already started replying to the user by accessing the
PrintWriter
orServletOutputStream
, you must use theinclude
method instead.Including a Request
The
include
method of theRequestDispatcher
interface provides the calling servlet the ability to respond to the client, but to use theRequestDispatcher
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 thePrintWriter
andServletOutputStream
objects before and after it calls theinclude
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 |