本文转载自: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) 方法实现转发。关于转发的具体操作,有如下几点需要注意:

  1. 转发只能在同一个应用的组件之间进行,不可以转发给其他应用的地址。
  2. 转发的地址可以用 “相对地址” 方式,也可以用 “绝对地址” 方式。但需要注意的是:用绝对地址方式时,应从应用名后 (Context path) 开始。例如:要转发到的地址为:http://192.168.5.100/tst/jsp/somewhere.jsp (其中 tst 为应用名),对应的绝对地址为:“/jsp/somewhere.jsp”。这是很好理解的,因为转发只能转到本应用内的地址,所以绝对地址是没有必要包含应用名的。
  3. 组件之间通过转发来分工协作,势必涉及数据的传递,可以通过 request 对象传递数据。request对象的 setAttribute 和 getAttribute 分别用于以 “名称-对象对” 的形式存取数据。
  4. 在一个组件转发给另外一个组件之前,通过 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” 这一点和转发中的绝对地址表示是不同的。

关于重定向的具体操作,有如下几点需要注意:

  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 传递的概念了。在客户浏览器路径栏显示的是其重定向的路径,客户可以观察到地址的变化的。重定向行为是浏览器做了至少两次的访问请求的。

Servlet & JSP - 转发与重定向的区别的更多相关文章

  1. Servlet中转发和重定向的区别

    Servlet中页面的跳转有两种方式:转发和重定向. 1.转发和重定向的区别 ①转发是服务器行为,重定向是客户端行为. ②转发是浏览器发生了一次请求,重定向至少是两次请求. ③转发地址栏中的url不会 ...

  2. servlet之转发与重定向的区别

    转发(服务器端跳转):  一次请求 <jsp:forward> request.getRequestDispatcher("new.jsp").forward(requ ...

  3. jsp转发与重定向的区别

    1.转发的实现其实很简单,使用request的getRequestDispatch()方法得到RequestDispatch对象,然后在括号里放转发的地址,然后用这个对象调用forward()方法,里 ...

  4. JSP转发和重定向的区别

    重定向: response.sendRedirect("地址");         a. 页面地址显示最终页面         b. 不可向后传递参数         c. 跳到外 ...

  5. Servlet转发和重定向的区别

    附上视频教学的一张图: 区别: 1.转发产生一次请求,一次响应: 重定向产生2次请求 两次响应 2.转发客户端不可见的: 重定向客户端是可以察觉的. 3.转发时候url不变: 重定向URL会改变 案例 ...

  6. servlet(jsp)中的重定向和转发

    servlet(jsp)中的重定向和转发 由一个servlet(jsp)从内部转向还有一个servlet(jsp)有两种方式:转发和重定向. 转发:是由一个web组件(servlet)将未完毕的处理交 ...

  7. jsp内置对象 转发与重定向的区别

    jsp 内置对象  转发与重定向的比较 重定向和转发有一个重要的不同:当使用转发时,JSP容器将使用一个内部的方法来调用目标页面,新的页面继续处理同一个请求,而浏览器将不会知道这个过程. 与之相反,重 ...

  8. SERVLET API中转发与重定向的区别?

    SERVLET API中转发与重定向的区别? 1.转发(forward方法) 转发仅是容器中控制权的转向,在客户端浏览器地址栏中不会显示出转向后的地址. 转发是服务器请求资源,服务器直接访问目标地址的 ...

  9. Java中转发与重定向的区别

        转发与重定向的区别 转发是服务器行为,重定向是客户端行为 1.转发在服务器端完成的:重定向是在客户端完成的2.转发的速度快:重定向速度慢3.转发的是同一次请求:重定向是两次不同请求4.转发不会 ...

随机推荐

  1. opencv 彩色图像亮度、对比度调节 直方图均衡化

    直接上代码: #include <Windows.h> #include <iostream>// for stand I/O #include <string> ...

  2. C# winform 最小化到电脑右下角

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  3. 学习LINQ,发现一个好的工具。LINQPad!!

    今日学习LINQ,发现一个好的工具.LINQPad!! 此工具的好处在于,不需要在程序内执行,直接只用工具测试.然后代码通过即可,速度快,简洁方便. 可以生成其LINQ查询对应的lambda和SQL语 ...

  4. spring事务注解

    @Transactional只能被应用到public方法上, 对于其它非public的方法,如果标记了@Transactional也不会报错,但方法没有事务功能. Spring使用声明式事务处理,默认 ...

  5. C#不错的扩展工具类

    FSLibExtension.NET https://github.com/iccfish/FSLib.Extension WebEssentials2013 https://github.com/i ...

  6. 将Java程序作成exe文件的几种方法【转载】

    看到网上有同志的介绍将Java程序作成exe文件的方法,写的不错,但是也许是这篇文章完成的时间比较早,许多内容已经不合适了.我在这里补充几条: 一.exe4j 说明:exe4j可以将Jar文件制作成e ...

  7. password安全之动态盐

    首先,我们看看什么是盐:http://zh.wikipedia.org/zh/%E7%9B%90_%28%E5%AF%86%E7%A0%81%E5%AD%A6%29 ,再MD5是d16e970d6e5 ...

  8. 【android】在eclipse中查看genymotion模拟器的sd卡文件夹

    假设用google自带模拟器或者真机调试时,sd卡文件夹是在/mnt/sdcard.这个相信大家都知道. 但是今天用genymotion调试时.发现根本打不开/mnt/sdcard这个文件夹,当时也没 ...

  9. 安装 Nginx 并配置负载均衡

    1,在节点 192.168.1.40 上执行安装 nginx,操作如下: 01 02 03 sudo apt-add-repository ppa:nginx/development sudo apt ...

  10. 个人对maven pom.xml文件的理解

    如:一个项目可能需要引用另外两个项目的类.. 如 项目cswebbefore  需要引用cswebservice 和reports 这三个项目都有各自的pom.xml文件 cswebservice 项 ...