转发和重定向的区别

来源:互联网 发布:js隐藏tr 编辑:程序博客网 时间:2024/05/06 21:50

请求转发和重定向的区别 一、调用方式 我们知道,在 servlet 中调用转发、重定向的语句如下: request.getRequestDispatcher("new.jsp").forward(request, response);//转发到 new.jsp response.sendRedirect("new.jsp");//重定向到 new.jsp 在 jsp 页面中你也会看到通过下面的方式实现转发: <jsp:forward page="apage.jsp" /> 当然也可以在 jsp 页面中实现重定向: <%response.sendRedirect("new.jsp");//重定向到 new.jsp%> 二、本质区别 解释一 一句话,转发是服务器行为,重定向是客户端行为。为什么这样说呢,这就要看两个动作的 工作流程: 转发过程:客户浏览器发送 http 请求----web 服务器接受此请求--》调用内部的一个方法在 容器内部完成请求处理和转发动作----》将目标资源发送给客户;在这里,转发的路径必须 是同一个 web 容器下的 url,其不能转向到其他的 web 路径上去,中间传递的是自己的容器 内的 request。在客户浏览器路径栏显示的仍然是其第一次访问的路径,也就是说客户是感 觉不到服务器做了转发的。转发行为是浏览器只做了一次访问请求。 重定向过程:客户浏览器发送 http 请求----web 服务器接受后发送 302 状态码响应及对应 新的 location 给客户浏览器--》客户浏览器发现是 302 响应,则自动再发送一个新的 http 请 求,请求 url 是新的 location 地址----》服务器根据此请求寻找资源并发送给客户。在这里 location 可以重定向到任意 URL,既然是浏览器重新发出了请求,则就没有什么 request 传 递的概念了。 在客户浏览器路径栏显示的是其重定向的路径, 客户可以观察到地址的变化的。 重定向行为是浏览器做了至少两次的访问请求的。 解释二 重定向,其实是两次 request, 第一次,客户端 request A,服务器响应,并 response 回来,告诉浏览器,你应该去 B。这个 时候 IE 可以看到地址变了,而且历史的回退按钮也亮了。重定向可以访问自己 web 应用以 外的资源。在重定向的过程中,传输的信息会被丢失。 例子: 请求转发是服务器内部把对一个 request/response 的处理权,移交给另外一个 对于客户端而言,它只知道自己最早请求的那个 A,而不知道中间的 B,甚至 CD。 传输 的信息不会丢失。 例子: 解释三 假设你去办理某个执照, 重定向:你先去了 局,局的人说: 这个事情不归我们管,去 ” ,然后,你就从 退了出来,自己乘车去了 局。 转发:你先去了 局,局看了以后,知道这个事情其实应该 局来管,但是他没有把你 退回来,而是让你坐一会儿,自己到后面办公室联系了 的人,让他们办好后,送了过来。 三、请求重定向与请求转发的比较 尽管 HttpServletResponse.sendRedirect 方法和 RequestDispatcher.forward 方法都可以让浏览器 获得另外一个 URL 所指向的资源,但两者的内部运行机制有着很大的区别。下面是 HttpServletResponse.sendRedirect 方法实现的请求重定向与 RequestDispatcher.forward 方法实 现的请求转发的总结比较: (1RequestDispatcher.forward 方法只能将请求转发给同一个 WEB 应用中的组件;而 HttpServletResponse.sendRedirect 方法不仅可以重定向到当前应用程序中的其他资源,还可 以重定向到同一个站点上的其他应用程序中的资源,甚至是使用绝对 URL 重定向到其他站 点的资源。如果传递给 HttpServletResponse.sendRedirect 方法的相对 URL “/”开头,它 是相对于整个 WEB 站点的根目录;如果创建 RequestDispatcher 对象时指定的相对 URL 以 “/”开头,它是相对于当前 WEB 应用程序的根目录。 (2)调用 HttpServletResponse.sendRedirect 方法重定向的访问过程结束后,浏览器地址栏中 显 示 的 URL 会 发 生 改 变 , 由 初 始 的 URL 地 址 变 成 重 定 向 的 目 标 URL ; 而 调 用 RequestDispatcher.forward 方法的请求转发过程结束后, 浏览器地址栏保持初始的 URL 地址 不变。 (3HttpServletResponse.sendRedirect 方法对浏览器的请求直接作出响应,响应的结果就是 告诉浏览器去重新发出对另外一个 URL 的 访问请求,这个过程好比有个绰号叫浏览器” 的人写信找张三借钱,张三回信说没有钱,让浏览器去找李四借,并将李四现在的通信 地址告诉给了浏览器” 。于是, 浏览器又按张三提供通信地址给李四写信借钱,李四收 到信后就把钱汇给了 浏览器” 可见, 。 浏览器” 一共发出了两封信和收到了两次回复,浏 览器也知道他借到的钱出自李四之手。RequestDispatcher.forward 方 法在服务器端内部将 请求转发给另外一个资源, 浏览器只知道发出了请求并得到了响应结果, 并不知道在服务器 程序内部发生了转发行为。这个过程好比绰号叫浏览器的人写信找张三借钱,张三没有 钱, 于是张三找李四借了一些钱, 甚至还可以加上自己的一些钱, 然后再将这些钱汇给了 浏 览器” 。可见, 浏览器只发 出了一封信和收到了一次回复,他只知道从张三那里借到了 钱,并不知道有一部分钱出自李四之手。 (4RequestDispatcher.forward 方法的调用者与被调用者之间共享相同的 request 对象和 response 对象,它们属于同一个访问请求和响应过程;而 HttpServletResponse.sendRedirect 方法调用者与被调用者使用各自的 request 对象和 response 对象,它们属于两个独立的访问 请求和响应过程。对于同一个 WEB 应用程序的内部资源之间的跳转,特别是跳转之前要对 请求进行一些前期预处理,并要使用 HttpServletRequest.setAttribute 方法传递预处理结果, 那就应该使用 RequestDispatcher.forward 方法。不同 WEB 应用程序之间的重定向,特别是 要 重 定 向 到 另 外 一 个 WEB 站 点 上 的 资 源 的 情 况 , 都 应 该 使 用 HttpServletResponse.sendRedirect 方法。 (5)无论是 RequestDispatcher.forward 方法,还是 HttpServletResponse.sendRedirect 方法, 在调用它们之前, 都不能有内容已经被实际输出到了客户端。 如果缓冲区中已经有了一些内 容,这些内容将被从缓冲区中清除。 

原创粉丝点击