Reading – Java™ Servlet Specification Version 2.4 – Dispatching Requests

Obtaining a RequestDispatcher

可通过 ServletContext 的如下方法获得一个 RequestDispatcher 的对象:

• getRequestDispatcher
• getNamedDispatcher

getRequestDispatcher 方法的参数是一个字符串, 描述位于 ServletContext 中的一个路径. 这个路径必须是相对于 ServletContext root 的且以一个 ‘/’ 开头. 这个方法是用这个路径查找 servlet, 包装为一个 RequestDispatcher 对象, 并返回. If no servlet can be resolved based on the given path, a RequestDispatcher is provided that returns the content for that path.

getNamedDispatcher 方法也是一个字符串参数, 指出为 ServletContext 所知的 servlet 的名字. 如果找到了 servlet, 则它将被包装为一个 RequestDispatcher 对象并返回. 如果依据给定名字并没有 servlet, 则该方法必须返回 null.
为了允许使用相对于当前请求的路径的相对路径(不是相对于 ServletContext 的根路径)来获得 RequestDispatcher 对象, ServletRequest 接口提供了 getRequestDispatcher 方法.

servlet container 使用 request 对象中的信息将给定的相对于当前 servlet 的相对路径转化为完整路径. 例如, 在一个 context 根路径为 ’/’ 并且请求为 /garden/tools.html 的情况下, 通过 ServletRequest.getRequestDispatcher(“header.html”) 得到的一个 request dispatcher 与直接调用 ServletContext.getRequestDispatcher(“/garden/header.html”) 是完全相同的.

Query Strings in Request Dispatcher Paths

ServletContext and ServletRequest 创建 RequestDispatcher 对象的方法允许向参数路径追加 query string. 例如, 开发人员可能通过如下代码获得一个 RequestDispatcher:

String path = “/raisins.jsp?orderno=5”;
RequestDispatcher rd = context.getRequestDispatcher(path);
rd.include(request, response);

query string 里指定的参数优先于被传递给被包含 servlet 的同名参数(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.

Using a Request Dispatcher

RequestDispatcher 接口提供了 include 和 forward 方法. 它们的参数既可以是传递给 service 方法的 request and response, 也可以是 request and response wrapper classes 的子类的实例. 在后一种情况下, wrapper 实例必须 wrap servlet container 所传递给 service 方法的 request or response 对象.

Container Provider 应当确保将请求 dispatch 到 target servlet 这一过程是在与原先 request 相同的线程内.

The Include Method

RequestDispatcher 接口的 include 方法在任何时候都可能被调用. include 方法的 target servlet 可访问 request 对象的任何信息, 但对 response 对象的使用则受限较多.

它只能向 response 对象的 ServletOutputStream or Writer 写数据, 将所写内容追加在 response buffer 的尾端进行提交, 或者明确调用 ServletResponse 接口的 flushBuffer 方法. 它不能设置 headers 或者调用任何会影响到 response headers 的方法. 任何这种企图都必须被忽略掉.

除了通过 getNamedDispatcher 方法得到的 servlets 外, 被另一个 servlet 使用 RequestDispatcher 的 include 方法所调用的 servlet 能够访问到它被调用的 path.

servlet container 中, 如下的 request attributes 必须设置:

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

这些 attributes 可以被 included 的 servlet 通过 request 对象的 getAttribute 方法访问到. 它们的值必须等于被 included servlet 的 request URI, context path, servlet path, path info, and query string.

如果 included servlet 是通过 getNamedDispatcher 方法得到的, 那么(在 servlet container 中)这些 attributes 务必不可设置.

可参考另一篇文章《servlet 2.4 RequestDispatcher 的一些要点

The Forward Method

只有当还没有任何输出提交给客户端时, 主 servlet 才可能调用 RequestDispatcher 的 forward 方法. 如果在 response buffer 里已经存在输出数据, 但还没有提交, 则这些内容必须在目标 servlet 的 service 方法调用之前被清空掉. 如果 response 已经被提交, 必须抛出一个 IllegalStateException.

暴露给目标 servlet 的 request 对象的 path 信息必须反映的是用于获得这个 RequestDispatcher 的 path.

唯一例外的是如果 RequestDispatcher 是通过 getNamedDispatcher 方法得到的. 在这种情形下, request 对象的 path 信息必须反映的是原始 request 的 path 信息.

在 RequestDispatcher 接口的 forward 方法返回之前, response 内容必须被发送并提交, 最后由 servlet container 关闭掉.

Query String

除通过 getNamedDispatcher 方法所获得的 servlets 外, 由另外一个 servlet 使用 RequestDispatcher 接口的 forward 方法所调用的 servlet 可以访问原始 request 的 path 信息.

如下 request attributes (注: servlet container)必须设置:

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

这些 attributes 的值必须等于主 servlet 的 request 对象分别调用 getRequestURI, getContextPath, getServletPath, getPathInfo, getQueryString 方法得到的值(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.).

这些 attributes 可从 forwarded servlet 的 request 对象的 getAttribute 方法访问到. 需注意的是这些 attributes 必须反映出最原始 request 中的信息, 甚至在多次 forwards 和 includes 情形下(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).

如果被 forwarded servlet 是使用 getNamedDispatcher 方法得到的, 这些属性(servlet container)务必不可设置.

可参考另一篇文章《servlet 2.4 RequestDispatcher 的一些要点

Error Handling

如果一个 request dispatcher 的 target servlet 抛出了一个 runtime exception 或者一个 checked exception (ServletException or IOException), 该 exception 应当传播给主(calling) servlet. All other exceptions should be wrapped as ServletExceptions and the root cause of the exception set to the original exception, as it should not be propagated.

By javafuns on December 31, 2008 at 22:57 · Views: 640 · Permalink · RSS
Categorized in: Java · Tagged with: ,
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...

Leave a Reply


  • Highest Rated

  • My PicasaPhotos

    IMG_0521.JPG

    IMG_0694.JPG

    IMG_0570.JPG

  • RSS My del.icio.us

  • My RSS