| C H A P T E R 8 |
|
Dispatching Requests |
When building a web application, it is often useful to forward the processing of a request to another servlet or to include the output of another servlet in the response. The RequestDispatcher interface provides a mechanism to accomplish this.
An object implementing the RequestDispatcher interface may be obtained from the ServletContext via the following methods:
The getRequestDispatcher method takes a String argument describing a path within the scope of the ServletContext. This path must be relative to the root of the ServletContext and begin with a “/”. The method uses the path to look up a servlet, using the servlet path matching rules in Chapter 11, wraps it with a RequestDispatcher object, and returns the resulting object. If no servlet can be resolved based on the given path, a RequestDispatcher is provided that returns the content for that path. If no resource is associated with the given path, the method must return null.
The getNamedDispatcher method takes a String argument indicating the name of a servlet known to the ServletContext. If a servlet is found, it is wrapped with a RequestDispatcher object and the object is returned. If no servlet is associated with the given name, the method must return null.
To allow RequestDispatcher objects to be obtained using relative paths that are relative to the path of the current request (not relative to the root of the ServletContext), the getRequestDispatcher method is provided in the ServletRequest interface.
The behavior of this method is similar to the method of the same name in the ServletContext. The servlet container uses information in the request object to transform the given relative path against the current servlet to a complete path. For example, in a context rooted at “/” and a request to /garden/tools.html, a request dispatcher obtained via ServletRequest.getRequestDispatcher(“header.html”) will behave exactly like a call to ServletContext.getRequestDispatcher(“/garden/header.html”).
The ServletContext and ServletRequest methods that create RequestDispatcher objects using path information allow the optional attachment of query string information to the path. For example, a developer may obtain a RequestDispatcher by using the following code:
String path = “/raisins?orderno=5”; RequestDispatcher rd = context.getRequestDispatcher(path); rd.include(request, response); |
Parameters specified in the query string used to create the RequestDispatcher take precedence over other parameters of the same name passed to the included servlet. The parameters associated with a RequestDispatcher are scoped to apply only for the duration of the include or forward call.
To use a request dispatcher, a servlet calls either the include method or forward method of the RequestDispatcher interface. The parameters to these methods can be either the request and response arguments that were passed in via the service method of the javax.servlet.Servlet interface, or instances of subclasses of the request and response wrapper classes. In the latter case, the wrapper instances must wrap the request or response objects that the container passed into the service method.
The container provider should ensure that the dispatch of the request to a target servlet occurs in the same thread as the original request.
The include method of the RequestDispatcher interface may be called at any time. The target servlet of the include method has access to all aspects of the request object, but its use of the response object is more limited. It can only write information to the ServletOutputStream or Writer of the response object and commit a response by writing content past the end of the response buffer, or by explicitly calling the flushBuffer method of the ServletResponse interface. It cannot set headers or call any method that affects the headers of the response. Any attempt to do so must be ignored.
Except for servlets obtained by using the getNamedDispatcher method, a servlet that has been invoked by another servlet using the include method of RequestDispatcher has access to the path by which it was invoked.
The following request attributes must be set:
These attributes are accessible from the included servlet via the getAttribute method on the request object and their values must be equal to the request URI, context path, servlet path, path information, and query string of the included servlet, respectively. If the request is subsequently included, these attributes are replaced for that include.
If the included servlet was obtained by using the getNamedDispatcher method, these attributes must not be set.
The forward method of the RequestDispatcher interface may be called by the calling servlet only when no output has been committed to the client. If output data exists in the response buffer that has not been committed, the content must be cleared before the target servlet’s service method is called. If the response has been committed, an IllegalStateException must be thrown.
The path elements of the request object exposed to the target servlet must reflect the path used to obtain the RequestDispatcher.
The only exception to this is if the RequestDispatcher was obtained via the getNamedDispatcher method. In this case, the path elements of the request object must reflect those of the original request.
Before the forward method of the RequestDispatcher interface returns, the response content must be sent, committed, and closed by the servlet container.
The request dispatching mechanism is responsible for aggregating query string parameters when forwarding or including requests.
Except for servlets obtained by using the getNamedDispatcher method, a servlet that has been invoked by another servlet using the forward method of RequestDispatcher has access to the path of the original request.
The following request attributes must be set:
The values of these attributes must be equal to the return values of the HttpServletRequest methods getRequestURI, getContextPath, getServletPath, getPathInfo, getQueryString respectively, invoked on the request object passed to the first servlet object in the call chain that received the request from the client.
These attributes are accessible from the forwarded servlet via the getAttribute method on the request object. Note that these attributes must always reflect the information in the original request even under the situation that multiple forwards and subsequent includes are called.
If the forwarded servlet was obtained by using the getNamedDispatcher method, these attributes must not be set.
If the servlet that is the target of a request dispatcher throws a runtime exception or a checked exception of type ServletException or IOException, it should be propagated to the calling servlet. All other exceptions should be wrapped as ServletExceptions and the root cause of the exception set to the original exception because it should not be propagated.
Copyright © 2009 Sun Microsystems, Inc. All rights reserved.