Servlet & JSP - 转发与重定向的区别
本文转载自:http://blog.csdn.net/kobejayandy/article/details/13762043
转发
转发的原理,可以通过下图展示:

浏览器的请求发送给组件 1,组件 1 经过一些处理之后,将 request 和 response 对象 “传递” 给组件 2,由组件 2 继续处理,然后输出响应(当然,也可以继续向其他组件 “传递”),这个传递的过程称之为 “转发”。整个过程只涉及一次浏览器和服务器之间的 “请求-响应” ,转发过程中的组件共享同一个请求 (request) 和响应 (response) 对象。
转发的意义在于可以实现组件的 “分工”。在基于 MVC,多层结构的Web应用中,经常需要多个组件协同完成一次 “请求-响应” 工作,例如:用户要获取“设备列表信息”,提交请求至控制器组件(Servlet),该 Servlet 调用适当的 JavaBean 获取了 “设备列表” 数据然后再转发至 JSP 组件去显示信息。
RequestDispatcher 对象封装了转发操作。通过 request 的 getRequestDispatcher(String path) 方法获得 RequestDispatcher 对象,其中 String 类型参数path 表示要转发到的地址。调用 Dispacther 对象的 forward(request, response) 方法实现转发。关于转发的具体操作,有如下几点需要注意:
- 转发只能在同一个应用的组件之间进行,不可以转发给其他应用的地址。
- 转发的地址可以用 “相对地址” 方式,也可以用 “绝对地址” 方式。但需要注意的是:用绝对地址方式时,应从应用名后 (Context path) 开始。例如:要转发到的地址为:http://192.168.5.100/tst/jsp/somewhere.jsp (其中 tst 为应用名),对应的绝对地址为:“/jsp/somewhere.jsp”。这是很好理解的,因为转发只能转到本应用内的地址,所以绝对地址是没有必要包含应用名的。
- 组件之间通过转发来分工协作,势必涉及数据的传递,可以通过 request 对象传递数据。request对象的 setAttribute 和 getAttribute 分别用于以 “名称-对象对” 的形式存取数据。
- 在一个组件转发给另外一个组件之前,通过 response 输出的响应内容是没有意义的。在转发之前的通过 out 对象输出的内容最终不会输出到浏览器,这是由于 RequestDispatcher 在转发之前清空了输出缓冲区。但如果在转发之前输出的信息超出了缓冲区,或者调用了 out 对象的 flush() 方法,此响应内容已经输出到了客户端(称之为响应信息已提交),此时如果实施转发操作会抛出运行时异常:java.lang.IllegalStateException。
重定向
重定向的含义可以由下图说明:

浏览器向某组件发出请求信息,组件向浏览器发回一个重定向响应信息,该响应信息不包含具体的数据内容,只是在响应头信息中包含了需要重定向到的地址信息,该地址可以是任何有效的 URL。浏览器收到该重定向响应后会自动的向响应信息头中所指示的地址发出请求。整个重定向的过程涉及两次 “请求-响应”。具体的重定向响应格式如下所示:
HTTP/1.1 302 Moved Temporarily
Server: Apache-Coyote/1.1
Locatio :http://192.168.5.100:8080/tst/jsp/somewhere.jsp
Content-Length: 0
Date: Mon, 30 Jun 2008 03:52:54 GMT
注意:重定向响应中包含重定向地址的部分。
重定向可以通过 response 的 sendRedirect(String url) 方法来实现,注意 String 类型的参数 url 表示重定向到的地址,需要注意的是,如果表示重定向到本应用内的一个绝对地址时,要从应用名前开始,例如:tst 应用中的某个组件要重定向到本应用内的 /jsp/somewhere.jsp,则重定向的绝对地址应该是:“/tst/jsp/somewhere.jsp” 这一点和转发中的绝对地址表示是不同的。
关于重定向的具体操作,有如下几点需要注意:
使用 response.sendRedirect 时,前面不能有 HTML 输出。
这并不是绝对的,不能有 HTML 输出其实是指不能有 HTML 被送到了浏览器。事实上现在的 server 都有 cache 机制,一般在 8K(我是说JSP SERVER),这就意味着,除非你关闭了cache,或者你使用了out.flush() 强制刷新,那么在使用 sendRedirect 之前,有少量的HTML输出也是允许的。response.sendRedirect 之后,应该紧跟一句 return;
我们已经知道 response.sendRedirect 是通过浏览器来做转向的,所以只有在页面处理完成后,才会有实际的动作。既然你已经要做转向了,那么后的输出还有什么意义呢?而且有可能会因为后面的输出导致转向失败。
本质区别
一句话,转发是服务器行为,重定向是客户端行为。为什么这样说呢,这就要看两个动作的工作流程:
转发过程:客户浏览器发送 http 请求 -----> web服务器接受此请求 -----> 调用内部的一个方法在容器内部完成请求处理和转发动作 -----> 将目标资源发送给客户。在这里,转发的路径必须是同一个 web 容器下的 url,其不能转向到其他的 web 路径上去,中间传递的是自己的容器内的 request。在客户浏览器路径栏显示的仍然是其第一次访问的路径,也就是说客户是感觉不到服务器做了转发的。转发行为是浏览器只做了一次访问请求。
重定向过程:客户浏览器发送 http 请求 -----> web 服务器接受后发送 302 状态码响应及对应新的 location 给客户浏览器 -----> 客户浏览器发现是 302 响应,则自动再发送一个新的 http 请求,请求 url 是新的 location地址 -----> 服务器根据此请求寻找资源并发送给客户。在这里 location 可以重定向到任意 URL,既然是浏览器重新发出了请求,则就没有什么 request 传递的概念了。在客户浏览器路径栏显示的是其重定向的路径,客户可以观察到地址的变化的。重定向行为是浏览器做了至少两次的访问请求的。
Servlet & JSP - 转发与重定向的区别的更多相关文章
- Servlet中转发和重定向的区别
Servlet中页面的跳转有两种方式:转发和重定向. 1.转发和重定向的区别 ①转发是服务器行为,重定向是客户端行为. ②转发是浏览器发生了一次请求,重定向至少是两次请求. ③转发地址栏中的url不会 ...
- servlet之转发与重定向的区别
转发(服务器端跳转): 一次请求 <jsp:forward> request.getRequestDispatcher("new.jsp").forward(requ ...
- jsp转发与重定向的区别
1.转发的实现其实很简单,使用request的getRequestDispatch()方法得到RequestDispatch对象,然后在括号里放转发的地址,然后用这个对象调用forward()方法,里 ...
- JSP转发和重定向的区别
重定向: response.sendRedirect("地址"); a. 页面地址显示最终页面 b. 不可向后传递参数 c. 跳到外 ...
- Servlet转发和重定向的区别
附上视频教学的一张图: 区别: 1.转发产生一次请求,一次响应: 重定向产生2次请求 两次响应 2.转发客户端不可见的: 重定向客户端是可以察觉的. 3.转发时候url不变: 重定向URL会改变 案例 ...
- servlet(jsp)中的重定向和转发
servlet(jsp)中的重定向和转发 由一个servlet(jsp)从内部转向还有一个servlet(jsp)有两种方式:转发和重定向. 转发:是由一个web组件(servlet)将未完毕的处理交 ...
- jsp内置对象 转发与重定向的区别
jsp 内置对象 转发与重定向的比较 重定向和转发有一个重要的不同:当使用转发时,JSP容器将使用一个内部的方法来调用目标页面,新的页面继续处理同一个请求,而浏览器将不会知道这个过程. 与之相反,重 ...
- SERVLET API中转发与重定向的区别?
SERVLET API中转发与重定向的区别? 1.转发(forward方法) 转发仅是容器中控制权的转向,在客户端浏览器地址栏中不会显示出转向后的地址. 转发是服务器请求资源,服务器直接访问目标地址的 ...
- Java中转发与重定向的区别
转发与重定向的区别 转发是服务器行为,重定向是客户端行为 1.转发在服务器端完成的:重定向是在客户端完成的2.转发的速度快:重定向速度慢3.转发的是同一次请求:重定向是两次不同请求4.转发不会 ...
随机推荐
- hbase 学习笔记一---基本概念
说在前面,本文部分内容来源于社区官网经过适度翻译,部分根据经验总结,部分是抄袭网络博文,(不一一列举引用,在此致歉)一并列在一起,本文的目的,希望能总结出一些有用的,应该注意到的东西,基本 ...
- UVaLive 7361 Immortal Porpoises (矩阵快速幂)
题意:求Fibonacci的第 n 项. 析:矩阵快速幂,如果不懂请看http://www.cnblogs.com/dwtfukgv/articles/5595078.html 是不是很好懂呢. 代码 ...
- java的BigDecimal
java的BigDecimal 一般设计到高精度的加法或乘法或者阶乘的求和积都会用到BigDecimal这个类. import java.util.*;import java.math.BigDeci ...
- TChromeTabs 使用日记
1.如何让 Tab 在拖放时,拖放图形中带有 TabControl 的内容. 增加 ChromeTabs 的 NeedDragImageControl 事件,并在代码中设置 DragControl 为 ...
- 整数矩阵CMO 2102回馈(gauss整数解)
PS:今天上午,非常郁闷,有很多简单基础的问题搞得我有些迷茫,哎,代码几天不写就忘.目前又不当COO,还是得用心记代码哦! 本题是CMO(数学 Olympics) 2012 第二题 所以还是很坑的…… ...
- hadoop数据[Hadoop] 实际应用场景之 - 阿里
上班之余抽点时间出来写写博文,希望对新接触的朋友有帮助.明天在这里和大家一起学习一下hadoop数据 Hadoop在淘宝和支付宝的应用从09年开始,用于对海量数据的离线处置,例如对日志的分析,也涉及内 ...
- [Javascript] Either Functor
Either Functor: // API Right(val) // resolve the value Left(val) // return error message Examples: m ...
- onClick,onServerClick,onClientClick
<asp:button id=button1 runat=server test=button1 onclick=button1_onclick/> <input type=butt ...
- Linux守护进程(init.d和xinetd)
http://www.cnblogs.com/itech/archive/2010/12/27/1914846.html
- 获取文件属性信息之stat、fstat和lstat
UNIX文件系统是目录和文件组成的一种层次结构.目录(directory)是一个包含许多目录项的文件,在逻辑上,可以认为每个目录项都包含一个文件名,同时还包含说明该文件属性的信息.文件属性是指文件类型 ...