HTTP 请求转发、重定向和包含

使Web应用程序如此强大的原因之一是它们彼此链接和聚合信息资源。J2EE 平台为特定URL Web组件提供三种相互关联、 但是有区别的方式,以便使用其他URL的数据来创建响应。本技巧讨论了如何使用Java Servlet API来实现请求转发、URL重定向和包含。

请求转发

请求转发允许组件发送请求到某个应用程序中的URL,并通过同一应用程序中的不同URL中的组件来处理该请求。这种技术通常用于Web层控制器servlet 它检查Web请求中的数据,并将请求定向到合适的组件,以便进行处理。

Servlet可以使用javax.servlet.RequestDispatcher.forward方法来转发它所收到的HTTP 请求。接收转发请求的组件能够处理该请求并生成一个响应, 或者它还可以将请求转发到另一个组件。 最初请求的ServletRequest ServletResponse 对象被传递给转发目标组件。这允许目标组件访问整个请求上下文。请求可以只转发给同一应用程序上下文根中的组件,而不在应用程序之间转发。

表单通过POST方法发送给 DispatchDemoServlet 将完成本技巧中三个例子的处理。请求转发由servlet doForward 方法处理,代码如下。

  protected void doForward(HttpServletRequest req,
                           HttpServletResponse res)
     throws IOException, ServletException {


     String name = req.getParameter("name");


     // Look up the site by name
     String url = (String)_p.get(name);
     if (url == null) {
        url = "errorPage.html";
     }


     // Get the request dispatcher -- request will be
     // dispatched to this URL.
     RequestDispatcher rd =
        req.getRequestDispatcher(url);


     // Forward to requested URL
     rd.forward(req, res);
  }

POST参数“name”指出用户请求的文件的符号名。方法在散列表中查找该文件的URL (散列表从应用归档文件中的属性文件装载) 。然后方法从 HttpServletRequest 对象中获得 RequestDispatcher 对象。 RequestDispatcher Web容器来实现。调用rd.forward指示Web容器调用指定URLWeb组件。请求的结果是该URL的组件返回的任何内容

URL重定向

URL 重定向类似于请求转发, 但也有一些重要的区别。Web组件可以将请求重定向到任一URL 而不仅仅是同一应用上下文中的URL。但最初请求的内容(比如POST参数)丢失了。这是因为服务器与重定向请示的过程无关,这与请求转发的情况是一样的 URL通过使用HTTP META头部的Refresh功能来完成重定向工作。本质上就是, 服务器返回一个META标记,告诉浏览器直接去其他地方。这时,最初URL所附带POST数据就会丢失。

URL 重定向可以直接通过操作HTTP 头部来完成, 但首选的方式还是使用方法javax.servlet.ServletResponse.sendRedirect。这个方法的唯一参数就是重定向的目标URL

URL 重定向的示例代码使用了示例应用程序中index.html 文件的第二个表单。用户从java.sun.com网站的几个URL中选择一个, 然后单击GO。本例子对应于Tip 2 表单中的第2项。

该表单将选定的表单名作为POST方法的参数发送给 DispatchDemoServlet,它再调用方法doRedirect,代码如下所示:

  protected void doRedirect(HttpServletRequest req,
                            HttpServletResponse res)
     throws IOException, ServletException {


     String name = req.getParameter("name");


     // Look up the site by name
     String url = (String)_p.get(name);
     if (url == null) {
        url = "errorPage.html";
     }

      // Redirect request
     res.sendRedirect(url);
  }

以上是使用doForward 方法来完成请求转发的例子, doRedirect 方法使用用户从表单中选择的符号名来查找重定向的URL 然后doRedirect 方法调用 HttpServletResponse sendRedirect 方法,这就在请求中构造和设置了一个HTTP头部,并立即返回。浏览器将收到空的响应, 但因为有META头部,浏览器迅速发出另一个新URL的请求。

虽然servlet产生一个空响应, 但如果能在响应中包含一条消息,以解释请求正在重定向,这是一个不错的方法。还有一个好办法是在重定向失败时提供一个到重定向目标的链接。较老的浏览器可能无法实现Refresh功能,或者可能出于安全的原因,该功能已经关闭。链接最好放在例子servlet之外,以简化代码。

包含

到目前为止, 您已经学习了响应请求的两种方式:请求转发和URL 重定向。相反, 包含允许一个Web组件聚集来自几个其他Web组件的数据,并使用被聚集的数据来创建响应。这种技术通常用于模板处理器。这里一个结构化的模板(通常是JSP 页面)用于控制响应的布局。模板中每个页面区域的内容来自不同的URL,从而组成单个页面。这种技术能够为应该程序提供一致的外观和感觉。

多个Web组件的内容可以被包含在单个响应中。要包含响应中另一个URL的数据,先获得该UML RequestDispatcher,然后调用 RequestDispatcher的包含方法。

包含的示例代码使用了一组复选框, 每个复选框指明一个应用程序归档案中的HTML 文件。每个HTML 文件对应于一种包含在输出中颜色。用户可以通过选中复选框来选择多个文件,然后单击GO。这对应于Tip 2 表单中的第3项。

DispatchDemoServlet 使用了doInclude 方法来处理请求,如下所示:

// Given a list of checked files, include each one of
  // them in the output to form a compound document
  protected void doInclude(HttpServletRequest req,
                           HttpServletResponse res)
     throws IOException, ServletException {
     String name = req.getParameter("name");

      // Get the request dispatcher -- request will be
     // dispatched to this URL.
     RequestDispatcher rd;
     if ((rd = req.getRequestDispatcher("/header.html"))
        != null) {
        rd.include(req, res);
     }
     if ((rd = req
getRequestDispatcher("/footerhtml"))
        != null) {
        rd
include(req res);
     }

   String[] names = req.getParameterValues("color");
     String url;

      for (int i = 0; names != null &&
        i < names.length; i++) {
        if ((url = (String)_p.get(names[i])) == null) {
           continue;
        }

         if ((rd = req.getRequestDispatcher(url))
           != null) {
           rd.include(req, res);
        }
     }

      if ((rd = req.getRequestDispatcher("/footer.html"))
        != null) {
        rd.include(req, res);
     }
  }
}

注意doInclude方法如何多次调用包含。每次调用包含时,doInclude 必须获得合适URL RequestDispatcher。方法首先包含文件 /header.html。然后获得列表中的复选框的名字,再查找散列表中相应的URL。对于找到的每个URL doInclude为该URL 获取一个 RequestDispatcher,然后在输出中包含该URL的内容。对包含方法的调用将该URL的输出写入 HttpServletResponse 对象。最后, doInclude URL /footer.html (相对上下文根)的内容写入输出。

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值