转发与重定向详解 java面试题之----转发(forward)和重定向(redirect)的区别

一、定义

1、什么是转发与重定向

当客户端向服务器发送请求时,服务器收到请求后,会将请求封装成一个HttpServletRequest对象request,并且所有的请求参数都封装在request对象中,这个对象时Jsp的内置对象可以直接在Jsp中使用。服务器收到请求后,还需要请求别的页面,这是就有两种方式:请求转发和请求重定向。

  • 所谓请求转发,是服务器的行为,请求由服务器转发给另外一个页面处理,如何转发,何时转发,转发几次,客户端是不知道的。请求转发时,从发送第一次到最后一次请求的过程中,web容器只创建一次request和response对象,新的页面继续处理同一个请求。也可以理解为服务器将request对象在页面之间传递。
  • 所谓请求重定向,是客户端的行为,每次请求重定向都是由客户端发起的,也就是说重定向一次,就刷新request对象的属性,之前的request对象的属性值就失效了。

二、Java实现

2.1 Java中的请求转发(服务器跳转)

执行到跳转语句时就会立刻进行跳转,Java代码:

request.getRequestDispatcher("success.jsp").forward(request,response);

在jsp页面中你也会看到通过下面的方式实现转发:

<jsp:forward page="success.jsp" />

2.2 Java中的请求重定向(客户端跳转)

1、response.sendRedirect("apage.jsp"); 不能传递request 范围的属性 ,但是可以通过地址重写的方式向跳转页传递参数,因为该方法执行完之后就相当于一次http request 的结束,这是服务器会向客户端发送302 状态码和新的url ,告诉客户端重新发送request 请求到新的url ,然后客户端照此执行,执行即新的请求响应流程开始,服务器再重新创建HttpServletRequest 对象和HttpServletResponse 对象,此时两个请求已经不在一个线程了,所以request 和response 对象都不是开始的那个了;
2、response.setHeader("refresh","2;URL=index.jsp") 2 秒后跳转到其他页面;
3、<a href="http://www.baidu.com"> 百度</a> 超链接
4、表单提交

三、路径问题

转发和重定向的URLString前有加 / 为绝对路径 ;反之为相对路径。

3.1绝对路径

1、重定向的 / 表示:http://服务器ip:端口/

response.sendRedirect("/Manager/index.jsp")

生成的地址:web服务器本身地址+参数生成完整的URL 即:http://localhost:8080/Manager/index.jsp

2、请求转发的 / 表示:http://服务器ip:端口/项目名

request.getRequestDispatcher("/index.jsp").forward(request, response); 

生成的地址:http://localhost:8080/项目名/index.jsp

重定向是浏览器发来的,只知道发到某个服务器,但是不知道发到服务器的哪个project,所以需要自己用代码声明; 而请求转发是服务器某个project内部的转发,转来转去都是在某个project内部,所以不需要手动声明项目名。

3.2 相对路径

假设通过表单请求指定的Url资源 action="LoginServlet"
则表单生成的请求地址为:http://localhost:8080/项目名/LoginServlet

1、请求重定向:response.sendRedirect("Manager/index.jsp")
生成相对路径:http://localhost:8080/项目名/Manager/index.jsp
2、请求转发:相对路径情况下生成的完整URL与重定向方法相同。

四、HTTP中的重定向和请求转发的区别

4.1 调用方式 

我们知道,在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%>

4.2含义

重定向(Redirect)就是通过各种方法将各种网络请求重新定个方向转到其它位置(如:网页重定向、域名的重定向、路由选择的变化也是对数据报文经由路径的一种重定向)

请求转发是服务器内部进行转发。

4.3图片比较

    这里写图片描述

请求转发:是在客户端发起请求后,在服务器之间的跳转,然后服务器返回页面给客户端进行显示。此时地址栏的地址没有进行改变。

            这里写图片描述

重定向 客户端发起请求之后,服务器会将重定向的地址发给客户端,客户端将地址拿到之后,重新发起请求,服务器进行返回数据。地址栏的地址进行改变。

4.4 重定向内部源码

java是如何实现重定向 java里面使用这句话 resp.sendRedirect(url); 重定向。 *

复制代码
 public void sendRedirect(String location) throws IOException {
        this.sendRedirect(location, 302);
    }
 
    public void sendRedirect(String location, int status) throws IOException {
        if (this.isCommitted()) {
            throw new IllegalStateException(sm.getString("coyoteResponse.sendRedirect.ise"));
        } else if (!this.included) {
            this.resetBuffer(true);
 
            try {
                String locationUri;
                if (this.getRequest().getCoyoteRequest().getSupportsRelativeRedirects() && this.getContext().getUseRelativeRedirects()) {
                    locationUri = location;
                } else {
                    locationUri = this.toAbsolute(location);
                }
 
                this.setStatus(status);
                this.setHeader("Location", locationUri);
                if (this.getContext().getSendRedirectBody()) {
                    PrintWriter writer = this.getWriter();
                    writer.print(sm.getString("coyoteResponse.sendRedirect.note", new Object[]{RequestUtil.filter(locationUri)}));
                    this.flushBuffer();
                }
            } catch (IllegalArgumentException var5) {
                log.warn(sm.getString("response.sendRedirectFail", new Object[]{location}), var5);
                this.setStatus(404);
            }
 
            this.setSuspended(true);
        }
    }
复制代码

底层的实现方法如上,其实是 将状态改成 302 ,然后在返回头中添加一个 Location 的参数里面放请求转发的地址。当客户端收到这个返回后,拿到Location 里面的地址进行请求数据。地址栏的地址进行改变。

4.5 本质区别

解释一  

一句话,转发是服务器行为,重定向是客户端行为。为什么这样说呢,这就要看两个动作的工作流程:

转发过程:客户浏览器发送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,甚至C、D。 传输的信息不会丢失。

 例子: 

解释三
假设你去办理某个执照,

重定向:你先去了A局,A局的人说:“这个事情不归我们管,去B局”,然后,你就从A退了出来,自己乘车去了B局。

转发:你先去了A局,A局看了以后,知道这个事情其实应该B局来管,但是他没有把你退回来,而是让你坐一会儿,自己到后面办公室联系了B的人,让他们办好后,送了过来。

下面链接是一个博主的请求转发实例

    请求转发与请求重定向实例:https://www.cnblogs.com/ChrisMurphy/p/5059940.html

页面跳转的两种方式(转发和重定向)区别及应用场景分析

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

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

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

      3、HttpServletResponse.sendRedirect方法对浏览器的请求直接作出响应,响应的结果就是告诉浏览器去重新发出对另外一个URL的 访问请求,这个过程好比有个绰号叫“浏览器”的人写信找张三借钱,张三回信说没有钱,让“浏览器”去找李四借,并将李四现在的通信地址告诉给了“浏览器”。于是,“浏览器”又按张三提供通信地址给李四写信借钱,李四收到信后就把钱汇给了“浏览器”。可见,“浏览器”一共发出了两封信和收到了两次回复, “浏览器”也知道他借到的钱出自李四之手。

            RequestDispatcher.forward方法在服务器端内部将请求转发给另外一个资源,浏览器只知道发出了请求并得到了响应结果,并不知道在服务器程序内部发生了转发行为。这个过程好比绰号叫“浏览器”的人写信找张三借钱,张三没有钱,于是张三找李四借了一些钱,甚至还可以加上自己的一些钱,然后再将这些钱汇给了“浏览器”。可见,“浏览器”只发 出了一封信和收到了一次回复,他只知道从张三那里借到了钱,并不知道有一部分钱出自李四之手。

       4、RequestDispatcher.forward方法的调用者与被调用者之间共享相同的request对象和response对象,它们属于同一个访问请求和响应过程;

              HttpServletResponse.sendRedirect方法调用者与被调用者使用各自的request对象和response对象,它们属于两个独立的访问请求和响应过程。

    对于同一个WEB应用程序的内部资源之间的跳转,特别是跳转之前要对请求进行一些前期预处理,并要使用HttpServletRequest.setAttribute方法传递预处理结果,那就应该使用RequestDispatcher.forward方法。不同WEB应用程序之间的重定向,特别是要重定向到另外一个WEB站点上的资源的情况,都应该使用HttpServletResponse.sendRedirect方法。

        5、无论是RequestDispatcher.forward方法,还是HttpServletResponse.sendRedirect方法,在调用它们之前,都不能有内容已经被实际输出到了客户端。如果缓冲区中已经有了一些内容,这些内容将被从缓冲区中。

转发和重定向的图解 

两种跳转获得对象的方式


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

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

转发和跳转的小结
      1、转发使用的是getRequestDispatcher()方法;重定向使用的是sendRedirect();

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

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

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

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

转发和重定向的选择
      1、重定向的速度比转发慢,因为浏览器还得发出一个新的请求,如果在使用转发和重定向都无所谓的时候建议使用转发。

      2、因为转发只能访问当前WEB的应用程序,所以不同WEB应用程序之间的访问,特别是要访问到另外一个WEB站点上的资源的情况,这个时候就只能使用重定向了。

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

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

       但是,使用重定向不太方便的地方是,使用它无法将值轻松地传递给目标页面。而采用转发,则可以简单地将属性添加到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:/……";
}
 
复制代码

面试真题:

java面试题之----转发(forward)和重定向(redirect)的区别

重定向和请求转发的区别 数据库的事物

回答总结:

在servlet中调用转发:
request.getRequestDispatcher("new.jsp").forward(request,response);//转发到new.jsp
在servlet中调用重定向:
response.sendRedirect("new.jsp");//重定向到new.jsp


转发与重定向的区别:
1.转发是服务器行为;重定向是客户端行为。转发在服务器端完成的;重定向是在客户端完成的。

2.转发的速度快;重定向速度慢。

3.转发的是同一次请求;重定向是两次不同请求。

4.转发不会执行转发后的代码;重定向会执行重定向之后的代码。

5.转发地址栏没有变化;重定向地址栏有变化。

6.转发必须是在同一台服务器下完成;重定向可以在不同的服务器下完成。

转发过程:
客户浏览器发送http请求,web服务器接受此请求,调用内部的一个方法在容器内部完成请求处理和转发动作,将目标资源发送给客户;在这里,转发的路径必须是同一个web容器下的url,其不能转向到其他的web路径上去,中间传递的是自己的容器内的request。在客户浏览器路径栏显示的仍然是其第一次访问的路径,也就是说客户是感觉不到服务器做了转发的。转发行为是浏览器只做了一次访问请求。

重定向过程:
客户浏览器发送http请求,web服务器接受后发送302状态码响应及对应新的location给客户浏览器,客户浏览器发现是302响应,则自动再发送一个新的http请求,请求url是新的location地址,服务器根据此请求寻找资源并发送给客户。在这里location可以重定向到任意URL,既然是浏览器重新发出了请求,则就没有什么request传递的概念了。在客户浏览器路径栏显示的是其重定向的路径,客户可以观察到地址的变化的。重定向行为是浏览器做了至少两次的访问请求的。

转发,一次请求
请求转发是指定服务器中的某一个资源(Servlet或JSP)在处理请求的过程中,将请求转发给一个其他的资源,让其他资源来处理请求。请求只发送一次即可。

重定向,两次请求
第一次,客户端发送request请求。A,服务器响应,并response回来,告诉浏览器,你应该去B。这个时候,客户端再发送request请求。B,服务器响应,并response回来。表现为:可以看到地址变了,而且历史的回退按钮也亮了。重定向可以访问自己web应用以外的资源。在重定向的过程中,传输的信息会被丢失。

参看链接:

https://www.cnblogs.com/2019wxw/p/10898010.html

https://blog.csdn.net/fighting_sxw/article/details/79302512

4.1 调用方式 

我们知道,在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%>

4.2含义

重定向(Redirect)就是通过各种方法将各种网络请求重新定个方向转到其它位置(如:网页重定向、域名的重定向、路由选择的变化也是对数据报文经由路径的一种重定向)

请求转发是服务器内部进行转发。

4.3图片比较

    这里写图片描述

请求转发:是在客户端发起请求后,在服务器之间的跳转,然后服务器返回页面给客户端进行显示。此时地址栏的地址没有进行改变。

            这里写图片描述

重定向 客户端发起请求之后,服务器会将重定向的地址发给客户端,客户端将地址拿到之后,重新发起请求,服务器进行返回数据。地址栏的地址进行改变。

4.4 重定向内部源码

java是如何实现重定向 java里面使用这句话 resp.sendRedirect(url); 重定向。 *

复制代码
 public void sendRedirect(String location) throws IOException {
        this.sendRedirect(location, 302);
    }
 
    public void sendRedirect(String location, int status) throws IOException {
        if (this.isCommitted()) {
            throw new IllegalStateException(sm.getString("coyoteResponse.sendRedirect.ise"));
        } else if (!this.included) {
            this.resetBuffer(true);
 
            try {
                String locationUri;
                if (this.getRequest().getCoyoteRequest().getSupportsRelativeRedirects() && this.getContext().getUseRelativeRedirects()) {
                    locationUri = location;
                } else {
                    locationUri = this.toAbsolute(location);
                }
 
                this.setStatus(status);
                this.setHeader("Location", locationUri);
                if (this.getContext().getSendRedirectBody()) {
                    PrintWriter writer = this.getWriter();
                    writer.print(sm.getString("coyoteResponse.sendRedirect.note", new Object[]{RequestUtil.filter(locationUri)}));
                    this.flushBuffer();
                }
            } catch (IllegalArgumentException var5) {
                log.warn(sm.getString("response.sendRedirectFail", new Object[]{location}), var5);
                this.setStatus(404);
            }
 
            this.setSuspended(true);
        }
    }
复制代码

底层的实现方法如上,其实是 将状态改成 302 ,然后在返回头中添加一个 Location 的参数里面放请求转发的地址。当客户端收到这个返回后,拿到Location 里面的地址进行请求数据。地址栏的地址进行改变。

4.5 本质区别

解释一  

一句话,转发是服务器行为,重定向是客户端行为。为什么这样说呢,这就要看两个动作的工作流程:

转发过程:客户浏览器发送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,甚至C、D。 传输的信息不会丢失。

 例子: 

解释三
假设你去办理某个执照,

重定向:你先去了A局,A局的人说:“这个事情不归我们管,去B局”,然后,你就从A退了出来,自己乘车去了B局。

转发:你先去了A局,A局看了以后,知道这个事情其实应该B局来管,但是他没有把你退回来,而是让你坐一会儿,自己到后面办公室联系了B的人,让他们办好后,送了过来。

下面链接是一个博主的请求转发实例

    请求转发与请求重定向实例:https://www.cnblogs.com/ChrisMurphy/p/5059940.html

页面跳转的两种方式(转发和重定向)区别及应用场景分析

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

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

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

      3、HttpServletResponse.sendRedirect方法对浏览器的请求直接作出响应,响应的结果就是告诉浏览器去重新发出对另外一个URL的 访问请求,这个过程好比有个绰号叫“浏览器”的人写信找张三借钱,张三回信说没有钱,让“浏览器”去找李四借,并将李四现在的通信地址告诉给了“浏览器”。于是,“浏览器”又按张三提供通信地址给李四写信借钱,李四收到信后就把钱汇给了“浏览器”。可见,“浏览器”一共发出了两封信和收到了两次回复, “浏览器”也知道他借到的钱出自李四之手。

            RequestDispatcher.forward方法在服务器端内部将请求转发给另外一个资源,浏览器只知道发出了请求并得到了响应结果,并不知道在服务器程序内部发生了转发行为。这个过程好比绰号叫“浏览器”的人写信找张三借钱,张三没有钱,于是张三找李四借了一些钱,甚至还可以加上自己的一些钱,然后再将这些钱汇给了“浏览器”。可见,“浏览器”只发 出了一封信和收到了一次回复,他只知道从张三那里借到了钱,并不知道有一部分钱出自李四之手。

       4、RequestDispatcher.forward方法的调用者与被调用者之间共享相同的request对象和response对象,它们属于同一个访问请求和响应过程;

              HttpServletResponse.sendRedirect方法调用者与被调用者使用各自的request对象和response对象,它们属于两个独立的访问请求和响应过程。

    对于同一个WEB应用程序的内部资源之间的跳转,特别是跳转之前要对请求进行一些前期预处理,并要使用HttpServletRequest.setAttribute方法传递预处理结果,那就应该使用RequestDispatcher.forward方法。不同WEB应用程序之间的重定向,特别是要重定向到另外一个WEB站点上的资源的情况,都应该使用HttpServletResponse.sendRedirect方法。

        5、无论是RequestDispatcher.forward方法,还是HttpServletResponse.sendRedirect方法,在调用它们之前,都不能有内容已经被实际输出到了客户端。如果缓冲区中已经有了一些内容,这些内容将被从缓冲区中。

转发和重定向的图解 

两种跳转获得对象的方式


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

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

转发和跳转的小结
      1、转发使用的是getRequestDispatcher()方法;重定向使用的是sendRedirect();

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

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

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

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

转发和重定向的选择
      1、重定向的速度比转发慢,因为浏览器还得发出一个新的请求,如果在使用转发和重定向都无所谓的时候建议使用转发。

      2、因为转发只能访问当前WEB的应用程序,所以不同WEB应用程序之间的访问,特别是要访问到另外一个WEB站点上的资源的情况,这个时候就只能使用重定向了。

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

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

       但是,使用重定向不太方便的地方是,使用它无法将值轻松地传递给目标页面。而采用转发,则可以简单地将属性添加到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:/……";
}
 
复制代码

面试真题:

java面试题之----转发(forward)和重定向(redirect)的区别

重定向和请求转发的区别 数据库的事物

回答总结:

在servlet中调用转发:
request.getRequestDispatcher("new.jsp").forward(request,response);//转发到new.jsp
在servlet中调用重定向:
response.sendRedirect("new.jsp");//重定向到new.jsp


转发与重定向的区别:
1.转发是服务器行为;重定向是客户端行为。转发在服务器端完成的;重定向是在客户端完成的。

2.转发的速度快;重定向速度慢。

3.转发的是同一次请求;重定向是两次不同请求。

4.转发不会执行转发后的代码;重定向会执行重定向之后的代码。

5.转发地址栏没有变化;重定向地址栏有变化。

6.转发必须是在同一台服务器下完成;重定向可以在不同的服务器下完成。

转发过程:
客户浏览器发送http请求,web服务器接受此请求,调用内部的一个方法在容器内部完成请求处理和转发动作,将目标资源发送给客户;在这里,转发的路径必须是同一个web容器下的url,其不能转向到其他的web路径上去,中间传递的是自己的容器内的request。在客户浏览器路径栏显示的仍然是其第一次访问的路径,也就是说客户是感觉不到服务器做了转发的。转发行为是浏览器只做了一次访问请求。

重定向过程:
客户浏览器发送http请求,web服务器接受后发送302状态码响应及对应新的location给客户浏览器,客户浏览器发现是302响应,则自动再发送一个新的http请求,请求url是新的location地址,服务器根据此请求寻找资源并发送给客户。在这里location可以重定向到任意URL,既然是浏览器重新发出了请求,则就没有什么request传递的概念了。在客户浏览器路径栏显示的是其重定向的路径,客户可以观察到地址的变化的。重定向行为是浏览器做了至少两次的访问请求的。

转发,一次请求
请求转发是指定服务器中的某一个资源(Servlet或JSP)在处理请求的过程中,将请求转发给一个其他的资源,让其他资源来处理请求。请求只发送一次即可。

重定向,两次请求
第一次,客户端发送request请求。A,服务器响应,并response回来,告诉浏览器,你应该去B。这个时候,客户端再发送request请求。B,服务器响应,并response回来。表现为:可以看到地址变了,而且历史的回退按钮也亮了。重定向可以访问自己web应用以外的资源。在重定向的过程中,传输的信息会被丢失。

参看链接:

https://www.cnblogs.com/2019wxw/p/10898010.html

https://blog.csdn.net/fighting_sxw/article/details/79302512

猜你喜欢

转载自www.cnblogs.com/vole/p/12463000.html
今日推荐