请求转发和重定向的区别及应用场景分析

页面跳转的两种方式(转发和重定向)区别详解:

做为一名程序员,特别是java web开发的程序员,在使用servlet/jsp的时候,咱们必需要知道实现页面跳转的两种方式的区别和联系:即转发和重定向的区别。java

      一、RequestDispatcher.forward方法只能将请求转发给同一个WEB应用中的组件;而HttpServletResponse.sendRedirect 方法不只能够重定向到当前应用程序中的其余资源,还能够重定向到同一个站点上的其余应用程序中的资源,甚至是使用绝对URL重定向到其余站点的资源。若是传递给HttpServletResponse.sendRedirect 方法的相对URL以“/”开头,它是相对于整个WEB站点的根目录;若是建立RequestDispatcher对象时指定的相对URL以“/”开头,它是相对于当前WEB应用程序的根目录。程序员

      二、调用HttpServletResponse.sendRedirect方法重定向的访问过程结束后,浏览器地址栏中显示的URL会发生改变,由初始的URL地址变成重定向的目标URL;而调用RequestDispatcher.forward 方法的请求转发过程结束后,浏览器地址栏保持初始的URL地址不变。web

      三、HttpServletResponse.sendRedirect方法对浏览器的请求直接做出响应,响应的结果就是告诉浏览器去从新发出对另一个URL的 访问请求,这个过程比如有个绰号叫“浏览器”的人写信找张三借钱,张三回信说没有钱,让“浏览器”去找李四借,并将李四如今的通讯地址告诉给了“浏览器”。因而,“浏览器”又按张三提供通讯地址给李四写信借钱,李四收到信后就把钱汇给了“浏览器”。可见,“浏览器”一共发出了两封信和收到了两次回复, “浏览器”也知道他借到的钱出自李四之手。RequestDispatcher.forward方法在服务器端内部将请求转发给另一个资源,浏览器只知道发出了请求并获得了响应结果,并不知道在服务器程序内部发生了转发行为。这个过程比如绰号叫“浏览器”的人写信找张三借钱,张三没有钱,因而张三找李四借了一些钱,甚至还能够加上本身的一些钱,而后再将这些钱汇给了“浏览器”。可见,“浏览器”只发 出了一封信和收到了一次回复,他只知道从张三那里借到了钱,并不知道有一部分钱出自李四之手。spring

       四、RequestDispatcher.forward方法的调用者与被调用者之间共享相同的request对象和response对象,它们属于同一个访问请求和响应过程;而HttpServletResponse.sendRedirect方法调用者与被调用者使用各自的request对象和response对象,它们属于两个独立的访问请求和响应过程。对于同一个WEB应用程序的内部资源之间的跳转,特别是跳转以前要对请求进行一些前期预处理,并要使用HttpServletRequest.setAttribute方法传递预处理结果,那就应该使用RequestDispatcher.forward方法。不一样WEB应用程序之间的重定向,特别是要重定向到另一个WEB站点上的资源的状况,都应该使用HttpServletResponse.sendRedirect方法。数据库

        五、不管是RequestDispatcher.forward方法,仍是HttpServletResponse.sendRedirect方法,在调用它们以前,都不能有内容已经被实际输出到了客户端。若是缓冲区中已经有了一些内容,这些内容将被从缓冲区中。跨域

以上五点的论述来源于:点击查看原文论述浏览器

 

1、转发和重定向的图解

1)请求转发:
  request.getRequestDispatcher(URL地址).forward(request, response)服务器

处理流程:session

  1. 客户端发送请求,Servlet作出业务逻辑处理。
  2. Servlet调用forword()方法,服务器Servlet把目标资源返回给客户端浏览器。

2)重定向:
  response.sendRedirect(URL地址)mvc

处理流程:

  1. 客户端发送请求,Servlet作出业务逻辑处理。
  2. Servlet调用response.sendReadirect()方法,把要访问的目标资源做为response响应头信息发给客户端浏览器。
  3. 客户端浏览器从新访问服务器资源xxx.jsp,服务器再次对客户端浏览器作出响应。

  以上两种状况,你都须要考虑Servlet处理完后,数据如何在jsp页面上呈现。图例是请求、响应的流程,没有标明数据如何处理、展示。

 

2、两种跳转得到对象的方式

//得到转发对象getRequestDispatcher()
HttpServletRequest(httpServletRequest).getRequestDispatcher
ServletContext.getRequestDispatcher();

//得到重定向对象sendRedirect()
HttpServletResponse(httpServletResponse).sendRedirect();

3、转发和重定向的路径问题

1)使用相对路径在重定向和转发中没有区别
2)重定向和请求转发使用绝对路径时,根/路径表明了不一样含义
重定向response.sendRedirect("xxx")是服务器向客户端发送一个请求头信息,由客户端再请求一次服务器。/指的Tomcat的根目录,写绝对路径应该写成"/当前Web程序根名称/资源名" 。如"/WebModule/login.jsp","/bbs/servlet/LoginServlet"
转发是在服务器内部进行的,写绝对路径/开头指的是当前的Web应用程序。绝对路径写法就是"/login.jsp"或"/servlet/LoginServlet"。

总结:以上要注意是区分是从服务器外的请求,还在是内部转发,从服务器外的请求,从Tomcat根写起(就是要包括当前Web的根);是服务器内部的转发,很简单了,由于在当前服务器内,/写起指的就是当前Web的根目录。

4、转发和重定向的区别

  1. request.getRequestDispatcher()是容器中控制权的转向,在客户端浏览器地址栏中不会显示出转向后的地址;服务器内部转发,整个过程处于同一个请求当中。
    response.sendRedirect()则是彻底的跳转,浏览器将会获得跳转的地址,并从新发送请求连接。这样,从浏览器的地址栏中能够看到跳转后的连接地址。不在同一个请求。重定向,实际上客户端会向服务器端发送两个请求。
    因此转发中数据的存取能够用request做用域:request.setAttribute(), request.getAttribute(),重定向是取不到request中的数据的。只能用session。

  2. forward()更加高效,在能够知足须要时,尽可能使用RequestDispatcher.forward()方法。(思考一下为何?)

  3. RequestDispatcher是经过调用HttpServletRequest对象的getRequestDispatcher()方法获得的,是属于请求对象的方法。
    sendRedirect()是HttpServletResponse对象的方法,即响应对象的方法,既然调用了响应对象的方法,那就代表整个请求过程已经结束了,服务器开始向客户端返回执行的结果。

  4. 重定向能够跨域访问,而转发是在web服务器内部进行的,不能跨域访问。

 

5、转发和跳转的小结     

      一、转发使用的是getRequestDispatcher()方法;重定向使用的是sendRedirect();

      二、转发:浏览器URL的地址栏不变。重定向:浏览器URL的地址栏改变;

      三、转发是服务器行为,重定向是客户端行为;

      四、转发是浏览器只作了一次访问请求。重定向是浏览器作了至少两次的访问请求;

      五、转发2次跳转之间传输的信息不会丢失,重定向2次跳转之间传输的信息会丢失(request范围)。

6、转发和重定向的选择     

      一、重定向的速度比转发慢,由于浏览器还得发出一个新的请求,若是在使用转发和重定向都无所谓的时候建议使用转发。

      二、由于转发只能访问当前WEB的应用程序,因此不一样WEB应用程序之间的访问,特别是要访问到另一个WEB站点上的资源的状况,这个时候就只能使用重定向了。

7、转发和重定向的应用场景     

   在上面我已经提到了,转发是要比重定向快,由于重定向须要通过客户端,而转发没有。有时候,采用重定向会更好,若须要重定向到另一个外部网站,则没法使用转发。另外,重定向还有一个应用场景:避免在用户从新加载页面时两次调用相同的动做。

       例如,当提交产品表单的时候,执行保存的方法将会被调用,并执行相应的动做;这在一个真实的应用程序中,颇有可能将表单中的全部产品信息加入到数据库中。可是若是在提交表单后,从新加载页面,执行保存的方法就颇有可能再次被调用。一样的产品信息就将可能再次被添加,为了不这种状况,提交表单后,你能够将用户重定向到一个不一样的页面,这样的话,这个网页任意从新加载都没有反作用;

       可是,使用重定向不太方便的地方是,使用它没法将值轻松地传递给目标页面。而采用转发,则能够简单地将属性添加到Model,使得目标视图能够轻松访问。因为重定向通过客户端,因此Model中的一切都会在重定向时丢失。但幸运的是,在Spring3.1版本之后,咱们能够经过Flash属性,解决重定向时传值丢失的问题。

       要使用Flash属性,必须在Spring MVC的配置文件中添加一个<annotation-driven/>。而后,还必须再方法上添加一个新的参数类型:org.springframework.web.servlet.mvc.support.RedirectAttributes。

 以下所示:

@RequestMapping(value="saveProduct",method=RequestMethod.POST)
public String saveProduct(ProductForm productForm,RedirectAttributes redirectAttributes){

//执行产品保存的业务逻辑等
//传递参数
redirectAttributes.addFlashAttribute("message","The product is saved successfully");

//执行重定向
return "redirect:/……";

 

  参考原文连接:https://blog.csdn.net/liubin5620/article/details/79922692https://blog.csdn.net/qq_34111779/article/details/78164027

  写博客是为了记住本身容易忘记的东西,另外也是对本身工做的总结,文章能够转载,无需版权。但愿尽本身的努力,作到更好,你们一块儿努力进步!

若是有什么问题,欢迎你们一块儿探讨,代码若有问题,欢迎各位大神指正!

相关文章
相关标签/搜索