请求转发和请求包含 - 公司荣誉 - 北京诚信汇发物流有限公司

请求转发和请求包含

作者:北京诚信汇发物流有限公司  来源:www.cxhfwL.com  发布时间:2017-09-04 13:36:29
请求转发和请求包含 1、Servlet 容器

\



  编程中的容器我们可以理解为程序运行时需要的环境,那么Tomcat 就是Servlet 的运行环境,就是一个Servlet 容器。Servlet 容器的作用是负责处理客户请求,当Servlet 容器获取到用户请求后,调用某个Servlet,并把Servlet 的执行结果返回给用户。

  Servlet 容器的工作流程:

  ● 当用户请求某个资源时,Servlet 容器使用ServletRequest 对象将用户的请求信息封装起来,然后调用 java Servlet API 中定义的Servlet 的生命周期方法,完成Servlet 的运行。

  ● Servlet 容器将Servlet 执行后需要返回用户的结果封装到 ServletResponse 对象中,最后由Servlet 容器发送给客户,完成对客户的一次服务过程。

  ● 每一个Servlet 都会执行 init()、service()、destory() 三个方法,在启动时调用一次init) 方法对参数进行初始化,在该Servlet 生存期间每当收到对其的请求时都会调用Service() 方法对请求进行处理,当容器销毁时自动调用 destory() 方法对Servlet 进行销毁。

2、请求转发和请求包含

  正是因为因为Servlet 中的service() 方法由Servlet 容器调用,所以一个 Servlet 的对象是无法调用另一个 Servlet 的方法的,但是在实际项目中,对于客户端请求做出的响应可能会复杂,需要多个Servlet 来协作完成,这就需要请求转发和请求包含技术了。但是,要注意,无论是请求转发还是请求包含,都是表示由多个Servlet 共同处理同一个请求。

(1)请求转发定义:

  Servlet(源组件)先对客户请求做一些预处理操作(一般是对响应头进行处理),然后把请求转发给其他Servlet(目标组件)来完成包括生成响应结果在内的后续操作。

  实现方法:request.getRequestDispatcher(“接收请求的Servlet 路径”). forward(request,response)

  getRequestDispatcher(String path):该方法的返回值类型是RequestDispatcher,请求发送器,该方法的参数是指明要接收请求的Servlet 的路径;

  forward(ServletRequest req,ServletResponse res):该方法是RequestDispatcher 接口的方法,将请求从一个 servlet 转发到服务器上的另一个资源(servlet、JSP 文件或 HTML 文件)。此方法允许一个 servlet 对请求进行初步处理,并使另一个资源生成响应。需要传递两个参数,这两个参数是当前Servlet 的request 对象和 response 对象传递过去的。

  forward() 方法的处理流程:

  ● 清空用于存放响应正文(响应体)数据的缓冲区。

  ● 如果目标组件为Servlet 或JSP,就调用它们的service() 方法,把该方法产生的响应结果发送到客户端,如果目标组件为文件系统中的静态 html 文档,就读去文档中的数据并把它发送到客户端。

  ● 由于 forward() 方法先清空用于存放响应正文数据的缓冲区,因此servlet源组件生成的响应结果不会被发送到客户端,只有目标组件生成的结果才会被发送到客户端,所以对源组件叫“留头不留体”,目标组件为“留体不留头”。

  ● 如果源组件在进行请求转发之前,已经提交了响应结果(例如调用了flush 或close() 方法),那么forward() 方法会抛出IllegalStateException。为了避免该异常,不应该在源组件中提交响应结果,所以叫留体抛异常。

(2)请求包含定义:

  Servlet(源组件)把其他Servlet(目标组件)生成的响应结果包含到自身的响应结果中。

  实现方式:request.getRequestDispatcher(“接收请求的Servlet 路径”). include(request,response)

  include(ServletRequest request,ServletResponse response):该方法是RequestDispatcher 接口的方法,表示包含。它的参数同forward() 方法的参数一样都是由当前Servlet传递过去的。

  包含与转发相比,源组件与被包含的目标组件的输出数据都会被添加到响应结果中,在目标组件中对响应状态代码或者响应头所做的修改都会被忽略,所以对源组件来说是“留头又留体”,对目标组件为“留体不留头”。

  注意:当Servlet 源组件调用 RequestDispatcher 的 forward 或 include 方法时,都要把当前的 ServletRequest 对象和ServletResponse 对象作为参数传给 forward 或 include 方法,这就使得源组件和目标组件共享同一个ServletRequest 对象和ServletResponse 对象,就实现了多个Servlet 协同处理同一个请求。

附:RequestDispatcher 接口

  RequestDispatcher 接口中定义了两个方法::forward() 方法和 include() 方法,它们分别用于将请求转发到 RequestDispatcher 对象封装的资源和将 RequestDispatcher 对象封装的资源作为当前响应内容的一部分包含进来.

3、请求转发(留头不留体,留体抛异常)

  AServlet(发送请求方):

package web.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class AServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); response.getWriter().print("您好!"); //response.getWriter().flush();//刷新会导致response的状态为已提交! // 转发不能在response提交之后,否则就会抛异常 request.getRequestDispatcher("/BServlet").forward(request, response); } }   BServlet(接收请求方):
package web.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class BServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { response.getWriter().print("我很棒!"); } }

  运行结果为:“我很棒!”(不会输出“你好!”)。

  我对留头不留体的分析:

企业建站2800元起,携手武汉肥猫科技,做一个有见地的颜值派!更多优惠请戳:孝感网站制作 http://xiaogan.666rj.com


上一篇:python 内存NoSQL数据库
下一篇:最后一页