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

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

时间: 2024-10-05 05:46:52

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

servlet之转发与重定向的区别

转发(服务器端跳转):  一次请求 <jsp:forward> request.getRequestDispatcher("new.jsp").forward(request, response); 重定向(客户端跳转):  两次请求 response.sendRedirect("new.jsp"); <a href="new.jsp">new.jsp</a> 转发重定向: 1.转发是在服务器端完成,因此称为服

servlet请求转发与重定向的区别

1.请求转发(forward) request.getRequestDispatcher("parameter").forward(request,response);跳转到指定的服务器资源,地址栏URL不变,请求响应不变. 2请求包含(include)request.getRequestDispatcher("parameter").include(request,response);跳转到指定的服务器资源且包含之前的资源,地址栏URL不变,请求响应不变. 注* 

Servlet 请求转发和重定向的区别

重定向和转发有一个重要的不同:当使用转发时,服务器将使用一个内部的方法来调用目标页面,新的页面继续处理同一个请求,而浏览器将不会知道这个过程. 与之相反,重定向方式的含义是第一个页面通知浏览器发送一个新的页面请求.因为,当你使用重定向时,浏览器中所显示的URL会变成新页面的URL, 而当使用转发时,该URL会保持不变.重定向的速度比转发慢,因为浏览器还得发出一个新的请求.同时,由于重定向方式产生了一个新的请求,所以经过一次重 定向后,request内的对象将无法使用. 怎么选择是重定向还是转发呢

JSP转发和重定向的区别

重定向: response.sendRedirect("地址"); a. 页面地址显示最终页面 b. 不可向后传递参数 c. 跳到外部站点 转发: request.getRequestDispatcher("地址").forward(request, response); a. 页面地址显示请求页面 b. 可以向后传递参数 c. 不可以跳到外部站点 造成区别的原因以及对这两者进行区别是,重定向发出两次请求,  转发只发一次请求. 打个简单的比方:我去XX部门办事,到

Servlet之转发和重定向的区别

应该是出自github上的项目JavaGuide 转发是服务器行为,重定向是客户端行为.转发(Forword) 通过RequestDispatcher对象的forward(HttpServletRequest request,HttpServletResponse response)方法实现的.RequestDispatcher可以通过HttpServletRequest 的getRequestDispatcher()方法获得.例如下面的代码就是跳转到login_success.jsp页面. r

servlet请求转发与重定向的区别------用生活实例来形象说明两者的区别

1,请求重定向:客户端行为,response.sendRedirect(),从本质上讲等同于两次请求,前一次的请求对象不会保持,地址栏的URL地址会改变. 2,请求转发:服务器行为,request.getRequsetDispatcher().forward(requset,response);是一次请求,转发后请求对象会保存,地址栏的URL地址不会改变.(服务器内部转发,所有客户端看不到地址栏的改变) 下面举个生活中的实例来说明: 请求重定向:就好比我们找一个A广告公司给设计名片,A明确告诉我

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

servlet(jsp)中的重定向和转发 由一个servlet(jsp)从内部转向另一个servlet(jsp)有两种方式:转发和重定向. 转发:是由一个web组件(servlet)将未完成的处理交给下一个web组件处理,转发的组件会共享request对象和response对象,从而实    现数据的共享. 可以使用以下方式进行转发:request.getRequestDispatcher("新资源").forward(req,resp); 注意: 1.转发之前不能执行response

Servlet转发和重定向的区别

附上视频教学的一张图: 区别: 1.转发产生一次请求,一次响应: 重定向产生2次请求 两次响应 2.转发客户端不可见的: 重定向客户端是可以察觉的. 3.转发时候url不变: 重定向URL会改变 案例:A与B两个Servlet的转发与重定向 转发:getRequestDispatcher(); ServletContext context= getServletContext(); RequestDispatcher dis = context.getRequestDispathcer("/b&

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

SERVLET API中转发与重定向的区别? 1.转发(forward方法) 转发仅是容器中控制权的转向,在客户端浏览器地址栏中不会显示出转向后的地址. 转发是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器,浏览器根本不知道服务器发送的内容是从哪儿来的,所以它的地址栏中还是原来的地址. 2.重定向(sendRedirect方法) 重定向是完全的跳转,浏览器将会得到跳转的地址,并重新发送请求链接.这样,从浏览器的地址栏中可以看到跳转后的链