天天看点

请求转发和请求包含1、Servlet 容器2、请求转发和请求包含3、请求转发(留头不留体,留体抛异常)4、请求包含(留头又留体)5、请求转发和请求包含的比较6、请求转发的应用:7、请求转发和重定向的区别  小结:在浏览器地址栏中输入某个URL地址或单击网页上的一个超链接时,浏览器发出的HTTP请求消息的请求方式为GET。如果网页中的<form>表单元素的method属性被设置为“GET”,浏览器提交这个FORM表单时生成的HTTP请求消息的请求方式也为GET。

请求转发和请求包含1、Servlet 容器2、请求转发和请求包含3、请求转发(留头不留体,留体抛异常)4、请求包含(留头又留体)5、请求转发和请求包含的比较6、请求转发的应用:7、请求转发和重定向的区别  小结:在浏览器地址栏中输入某个URL地址或单击网页上的一个超链接时,浏览器发出的HTTP请求消息的请求方式为GET。如果网页中的<form>表单元素的method属性被设置为“GET”,浏览器提交这个FORM表单时生成的HTTP请求消息的请求方式也为GET。

  编程中的容器我们可以理解为程序运行时需要的环境,那么tomcat 就是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 进行销毁。 

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

共同处理同一个请求。

  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。为了避免该异常,不应该在源组件中提交响应结果,所以叫留体抛异常。

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

  aservlet(发送请求方):

  bservlet(接收请求方):

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

    对于发出请求的aservlet是:留头不留体(设置的响应头可以留下,响应体被接收请求的 bservlet 响应体覆盖); 留体抛异常,就是说只要请求转发了,就要将请求完全由 bservlet 处理,aservlet就不能插手了,如果aservlet 也提交了对请求的处理,那么bservlet 就不能处理请求了(因为请求已经被aservlet 处理了,还处理啥) ,你安排人家处理请求,最终却由你处理了,当forward() 转发请求时,发现请求已经被处理,就会抛出异常。

    不过要注意,只有当aservlet 提交了处理(如例中手动flush将缓冲区内数据提交)才会抛出异常,如果没有提交,说明之前a对请求的处理还在缓冲区中,b就会直接将a的缓冲区清空,然后覆盖掉,就形成了之前的留头不留体。

  cservlet(发送请求方):

  dservlet(接收请求方):

  运行结果为:你好!我很棒!

  结果说明请求包含是多个servlet 共同处理一个请求的,并且发送方和接收方都能够留下响应体。

    请求转发和请求包含都是在处理一个相同的请求,多个servlet之间使用同一个 request 对象和 response 对象。

    ● 如果在aservlet中请求转发到bservlet,那么在aservlet中不允许再输出响应体,即不能使用response.getwriter() 和response.getoutputstream()

向客户端输出,这一工作交由bservlet来完成;如果是由aservlet请求包含bservlet,则没有这个限制。

    ● 请求转发不能设置响应体,但是可以设置响应头,简单来说就是“留头不留体”,例如:response.setcontenttype("text/html;charset=utf-8”)

是可以留下来的;请求包含不仅可以设置响应头,还可以设置响应体,简单来说就是“留头又留体“。

    ● 请求转发大多应用在servlet中,转发目标大多是jsp页面;请求包含大多应用在jsp页面中,完成多页面的合并。一般情况下经常使用的是请求转发。

  ● 在servlet中向数据库获取数据,保存到request域中;

  ● 转发到jsp页面,jsp从request域中获取数据,显示在页面上。

  ● 对于客户端浏览器来说,转发是一个请求,重定向是两个请求;

  ● 转发浏览器地址栏不变化,重定向会变成转发后的url ;

  ● 转发只能在一个项目内,而重定向没有限制,可以重定向到任意网址,如京东、淘宝等 ;

  ● 转发可以使用request 域传递数据,而重定向不能。因为转发是一个请求,重定向是两个请求;

  ● 转发只有一个请求,原来是什么请求方式就是什么方式;而重定向两个请求,第一个可能为post 可能为get ,但是第二个请求一定是get 。

请求转发和请求包含1、Servlet 容器2、请求转发和请求包含3、请求转发(留头不留体,留体抛异常)4、请求包含(留头又留体)5、请求转发和请求包含的比较6、请求转发的应用:7、请求转发和重定向的区别  小结:在浏览器地址栏中输入某个URL地址或单击网页上的一个超链接时,浏览器发出的HTTP请求消息的请求方式为GET。如果网页中的<form>表单元素的method属性被设置为“GET”,浏览器提交这个FORM表单时生成的HTTP请求消息的请求方式也为GET。