出处:http://blog.youkuaiyun.com/kobejayandy/article/details/13762043
1、转发只能在同一个应用的组件之间进行,不可以转发给其他应用的地址。
2、转发的地址可以用“相对地址”方式,也可以用“绝对地址”方式。但需要注意的是:用绝对地址方式时,应从应用名后(Context path)开始。例如:要转发到的地址为:http://192.168.5.100/tst/jsp/somewhere.jsp
3、组件之间通过转发来分工协作,势必涉及数据的传递,可以通过request对象传递数据。request对象的setAttribute和getAttribute分别用于以“名称-对象对”的形式存取数据。
4、在一个组件转发给另外一个组件之前,通过response输出的响应内容是没有意义的。在转发之前的通过out对象输出的内容最终不会输出到浏览器,这是由于RequestDispatcher在转发之前清空了输出缓冲区。但如果在转发之前输出的信息超出了缓冲区,或者调用了out对象的flush()方法,此响应内容已经输出到了客户端(称之为响应信息已提交),此时如果实施转发操作会抛出运行时异常:java.lang.IllegalStateException。
二、重定向
重定向的含义可以由下图说明:
HTTP/1.1302 Moved Temporarily
Server: Apache-Coyote/1.1
Location: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”这一点和转发中的绝对地址表示是不同的。
关于重定向的具体操作,有如下几点需要注意:
1、使用response.sendRedirect时,前面不能有HTML输出。
这并不是绝对的,不能有HTML输出其实是指不能有HTML被送到了浏览器。事实上现在的server都有cache机制,一般在8K(我是说JSP SERVER),这就意味着,除非你关闭了cache,或者你使用了out.flush()强制刷新,那么在使用sendRedirect之前,有少量的HTML输出也是允许的。
2、.response.sendRedirect之后,应该紧跟一句return;
我们已经知道response.sendRedirect是通过浏览器来做转向的,所以只有在页面处理完成后,才会有实际的动作。既然你已经要做转向了,那么后的输出还有什么意义呢?而且有可能会因为后面的输出导致转向失败。
三、本质区别
一句话,转发是服务器行为,重定向是客户端行为。为什么这样说呢,这就要看两个动作的工作流程:
转发过程:客户浏览器发送http请求----》web服务器接受此请求--》调用内部的一个方法在容器内部完成请求处理和转发动作----》将目标资源发送给客户;在这里,转发的路径必须是同一个web容器下的url,其不能转向到其他的web路径上去,中间传递的是自己的容器内的request。在客户浏览器路径栏显示的仍然是其第一次访问的路径,也就是说客户是感觉不到服务器做了转发的。转发行为是浏览器只做了一次访问请求。
重定向过程:客户浏览器发送http请求----》web服务器接受后发送302状态码响应及对应新的location给客户浏览器--》客户浏览器发现是302响应,则自动再发送一个新的http请求,请求url是新的location地址----》服务器根据此请求寻找资源并发送给客户。在这里 location可以重定向到任意URL,既然是浏览器重新发出了请求,则就没有什么request传递的概念了。在客户浏览器路径栏显示的是其重定向的路径,客户可以观察到地址的变化的。重定向行为是浏览器做了至少两次的访问请求的。