【Java.Web】Servlet —— 请求的转发和包含
2014-10-03 03:43
811 查看
请求的转发和包含
Servlet的service()方法是由Servlet容器来调用的,用户不能在一个Servlet对象中直接调用另一个Servlet对象的servie()方法,因为一个Servlet对象无法得到另一个Servlet对象的引用。但是web应用在响应客户端的一个请求时,有可能响应过程很复杂,需要多个web组件共同协作(参见上一节——动态生成图像)。尽管Servlet对象无法直接调用另一个Servlet对象的service()方法,但Servlet规范为Web组件之间的协作提供了两种途径:
请求转发
Servlet(源组件)先对客户请求做一些预处理操作,然后把请求转发给其他Web组件(目标组件)来完成包括生成响应结果在内的后续操作;
请求包含
Servlet(源组件)把其他Web组件(目标组件)生成的响应结果包含到自身的响应结果中;
请求转发 V.S. 请求包含
对于转发和包含,源组件和目标组件处理的都是同一个客户请求;源组件和目标组件共享同一个ServletRequest和ServletResponse对象
对于转发和包含,目标组件都可以为Servlet,JSP或HTML文档
对于转发和包含,都依赖与javax.servlet.RequestDispatcher接口
javax.servlet.RequestDispatcher接口
该接口表示请求分发器,Modifier and Type | Method and Description |
---|---|
void | forward(ServletRequest request, ServletResponse response) Forwards a request from a servlet to another resource (servlet, JSP file, or HTML file) on the server. |
void | include(ServletRequest request, ServletResponse response) Includes the content of a resource (servlet, JSP page, HTML file) in the response. |
forward()方法的处理流程如下:(1)清空用于存放响应正文数据的缓冲区;(2)如果目标组件为Servlet或JSP,就调用它们的service()方法,把该方法产生的响应结果发送到客户端,如果目标组件为文件系统中的静态html文档,就读去文档中的数据并把它发送到客户端。
由于forward()方法先清空用于存放响应正文数据的缓冲区,因此servlet源组件生成的响应结果不会被发送到客户端,只有目标组件生成的结果才会被发送到客户端;
如果源组件在进行请求转发之前,已经提交了响应结果(例如调用了flushBuffer方法,或者close()方法),那么forward()方法会抛出IllegalStateException。为了避免该异常,不应该在源组件中提交响应结果。
include()方法
包含与转发相比,源组件与被包含的目标组件的输出数据都会被添加到响应结果中
在目标组件中对响应状态代码或者响应头所做的修改都会被忽略
当Servlet源组件调用RequestDispatcher的forward或include方法时,都要把当前的ServletRequest对象和ServletResponse对象作为参数传给forward或include方法,这使得源组件和目标组件共享同一个ServletRequest对象和ServletResponse对象。
Servlet可以通过两个两种方式得到RequestDispatcher对象:
调用ServletContext的getRequestDispatcher(String path)方法,path参数指定目标组件的路径
path参数必须为绝对路径;绝对路径,就是以符号“/”开头的路径,“/”表示当前Web应用的URL路口
调用ServletRequest的getRequestDispatcher(String path)方法,path参数指定目标组件的路径
path参数既可以为绝对路径,也可以为相对路径;相对路径,就是相对于当前Servlet组件的路径,不以“/”开头
请求转发
如下实例:源servlet —— ForwardSourceServlet;目标servlet —— ForwardDestinationServlet;package com.gof.test.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.http.HttpServlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletContext; import javax.servlet.RequestDispatcher; public class ForwardSourceServlet extends HttpServlet { /** * */ private static final long serialVersionUID = 7412912720309987937L; @Override public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { String username = req.getParameter("username"); String message = null; if (username == null){ message = "Please input username."; }else{ message = "Hello " + username; } // add attribute to request req.setAttribute("msg", message); // forward the request to ForwardDestinationServlet ServletContext context = getServletContext(); RequestDispatcher dispatcher = context.getRequestDispatcher("/forwarddest"); // try to output something into response PrintWriter out = res.getWriter(); out.println("Output from ForwardSourceServlet before forwarding request"); if (dispatcher != null){ dispatcher.forward(req, res); } out.println("Output from ForwardSourceServlet after forwarding request"); out.close(); } }
package com.gof.test.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.GenericServlet; import javax.servlet.RequestDispatcher; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ForwardDestinationServlet extends HttpServlet { /** * */ private static final long serialVersionUID = 7412912720309987937L; @Override public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { String message = (String)req.getAttribute("msg"); PrintWriter out = res.getWriter(); out.println(message); out.close(); } }
在web.xml中注册:
<!-- Forward request --> <!-- test url = http://localhost:8080/base-webapp/forwardsrc?username=New User --> <servlet> <servlet-name>forwardsrc</servlet-name> <servlet-class>com.gof.test.servlet.ForwardSourceServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>forwardsrc</servlet-name> <url-pattern>/forwardsrc</url-pattern> </servlet-mapping> <servlet> <servlet-name>forwarddest</servlet-name> <servlet-class>com.gof.test.servlet.ForwardDestinationServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>forwarddest</servlet-name> <url-pattern>/forwarddest</url-pattern> </servlet-mapping>
访问如下URL:
http://localhost:8080/base-webapp/forwardsrc?username=New User
修改1:
在调用forward方法之前调用flush()/close()方法,将会抛出一个IllegalStateException异常;同时,目标组件中的内容不会输出:只会输出源组件前面输出的内容:
修改2:
将获取RequestDispatcher的方法参数path改为“forwarddest”,抛出IllegalArgumentException,提示参数没有以“/”开头。
修改3:
将获取RequestDispatcher的方法改为:
RequestDispatcher dispatcher = req.getRequestDispatcher("forwarddest");
可以正常运行。
请求包含
如下示例:源组件 —— IncludeSourceServlet;目标组件 —— includeheader.html,IncludeDestinationServlet,includefooter.html:package com.gof.test.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.http.HttpServlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletContext; import javax.servlet.RequestDispatcher; public class IncludeSourceServlet extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ resp.setContentType("text/html"); PrintWriter out = resp.getWriter(); out.println("<html><header><title>Include Test</title></header>"); out.println("<body>"); ServletContext context = getServletContext(); RequestDispatcher headDispatcher = context.getRequestDispatcher("/includeheader.html"); RequestDispatcher bodyDispatcher = context.getRequestDispatcher("/includedest"); RequestDispatcher footDispatcher = context.getRequestDispatcher("/includefooter.html"); headDispatcher.include(req, resp); bodyDispatcher.include(req, resp); footDispatcher.include(req, resp); out.println("</body></html>"); out.close(); } }
includeheader.html
<br/> This is from includeheader.html <br/>
package com.gof.test.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.http.HttpServlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletContext; import javax.servlet.RequestDispatcher; public class IncludeDestinationServlet extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ PrintWriter out = resp.getWriter(); out.println("<br/>This is from IncludeDestinationServlet<br/>"); } }
includefooter.html
<br/> This is from includefooter.html <br/>
在web.xml中注册:
<!-- Include request --> <!-- test url = http://localhost:8080/base-webapp/includesrc --> <servlet> <servlet-name>includesrc</servlet-name> <servlet-class>com.gof.test.servlet.IncludeSourceServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>includesrc</servlet-name> <url-pattern>/includesrc</url-pattern> </servlet-mapping> <servlet> <servlet-name>includedest</servlet-name> <servlet-class>com.gof.test.servlet.IncludeDestinationServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>includedest</servlet-name> <url-pattern>/includedest</url-pattern> </servlet-mapping>
在浏览器中访问如下的URL:
http://localhost:8080/base-webapp/includesrc
结果如下:
相关文章推荐
- javaweb-day06-4&5&6 (Servlet-Request-方法、表单获取客户端中文信息、URL编码、Request容器和请求转发、RequestDispatcher.include()
- JavaWeb 初步学习一(ServletConfig参数获取,ServletContext共享数据与请求转发)
- JavaWeb开发之深入分析请求转发和重定向的应用场景以及请求包含 (跟着龙哥学JavaWeb)
- javaweb servlet转发,包含,重定向; jsp转发,包含
- javaweb之请求转发和请求包含
- javaweb servlet中使用请求转发乱码的实现
- JavaWeb之Servlet:请求 与 响应
- Servlet 实现包含外部文件和转发请求
- servlet请求转发、包含以及重定向
- Servlet技术-请求转发,重定向和包含的关系
- javaWeb 复习系列(四)---- 多个请求映射到同一个 Servlet
- javaweb-day06-2&3 (Servlet - Response - 输出随机图片、请求重定向、web工程的URL地址写法、getOutputStream和getWriter互斥)
- java学习之Servlet请求转发之RequestDispatcher
- 10014---JavaWeb基础--请求重定向与请求转发
- Servlet中的请求转发与包含
- 【JavaWeb】 ServletContext以及讲解Servlet转发
- javaweb之request实现请求转发以及request域带数据给转发资源
- Servlet请求转发与包含
- javaWeb_14-request实现请求转发和mvc设计模式
- servlet获取表单提交的数据、请求转发、请求包含、请求重定向