关于
RequestDispatcher机制的文章,只看懂个大概,那位E文好,给翻译一下!
RequestDispatcher defines an object that receives
requests from the client and sends them to any resource (such as a servlet, HTML
file, or JSP file) on the server. The servlet container creates the RequestDispatcher object, which is used as a wrapper around
a server resource located at a particular path or given by a particular name.
An object implementing the RequestDispatcher
interface may be obtained via the following methods:
-
ServletContext.getRequestDispatcher(String path)
-
ServletContext.getNamedDispatcher(String name)
-
ServletRequest.getRequestDispatcher(String path)
The ServletContext.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, 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.
The ServletContext.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 ServletRequest.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").
RequestDispatcher creation and
using.
public class Dispatcher extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res) {
RequestDispatcher dispatcher =
request.getRequestDispatcher("/template.jsp");
if (dispatcher != null) dispatcher.forward(request, response);
}
}
forward should be called before the response has been
committed to the client (before response body output has been flushed). If the
response already has been committed, this method throws an IllegalStateException. Uncommitted output in the response
buffer is automatically cleared before the forward.
public class Dispatcher extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res) {
RequestDispatcher dispatcher =
getServletContext().getRequestDispatcher("/banner");
if (dispatcher != null) dispatcher.include(request, response);
}
}
Includes the content of a resource (servlet, JSP page, HTML file) in the
response. In essence, this method enables programmatic server-side includes. The
ServletResponse object has its path elements and
parameters remain unchanged from the caller's. The included servlet cannot
change the response status code or set headers; any attempt to make a change is
ignored.
package javax.servlet;
public interface RequestDispatcher {
public void forward(ServletRequest request, ServletResponse response)
throws ServletException, java.io.IOException;
public void include(ServletRequest request, ServletResponse response)
throws ServletException, java.io.IOException;
}
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.
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 and committed, and closed by the servlet container.
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.jsp?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.
Additional request-scoped attributes.
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:
-
javax.servlet.include.request_uri
-
javax.servlet.include.context_path
-
javax.servlet.include.servlet_path
-
javax.servlet.include.path_info
-
javax.servlet.include.query_string
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 info, 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.
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:
-
javax.servlet.forward.request_uri
-
javax.servlet.forward.context_path
-
javax.servlet.forward.servlet_path
-
javax.servlet.forward.path_info
-
javax.servlet.forward.query_string
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.