重定向和转发的区别

1. 重定向与转发的区别:

1.重定向访问服务器两次,转发只访问服务器一次。

2.转发页面的URL不会改变,而重定向地址会改变

3.转发只能转发到自己的web应用内,重定向可以重定义到任意资源路径。

4.转发相当于服务器跳转,相当于方法调用,在执行当前文件的过程中转向执行目标文件,两个文件(当前文件和目标文件)属于同一次请求,前后页 共用一个request,可以通过此来传递一些数据或者session信息,request.setAttribute()和 request.getAttribute()。而重定向会产生一个新的request,不能共享request域信息与请求参数

5.由于转发相当于服务器内部方法调用,所以转发后面的代码仍然会执行(转发之后记得return);重定向代码执行之后是方法执行完成之后进行重定向操作,也就是访问第二个请求,如果是方法的最后一行进行重定向那就会马上进行重定向(重定向也需要return)。

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

可以这么理解:

  转发相当于,张三向你借钱,但是你兜里没钱,所以你去找李四借到钱之后借给张三。对于张三而言并不知道你的钱是和李四借的。

  重定向相当于,张三向你借钱,你兜里没钱,你告诉他李四有钱,所以张三再次去找李四借钱。

2. 调用方式

转发和重定向在Java中的方法如下:

        request.getRequestDispatcher("/SecondServlet?addParam=newParam").forward(request, response);
        response.sendRedirect("/WebSocket/SecondServlet");

  WebSocket相当于项目名称,SecondServlet是具体的servlet请求。也就是转发不加项目名称,重定向可以写绝对URL,也可以写相对URL。

补充:3xx状态码与重定向相关。301是永久重定向,302是临时重定向,我们有时候希望发送永久重定向的code。上面sendRedirect默认是302。如下:

        response.setStatus(301);
        response.addHeader("Location", "/WebSocket/SecondServlet");

3. 应用场景

1. 转发  request.getRequestDispatcher().forward(request,response):

1、属于转发,也是服务器跳转,相当于方法调用,在执行当前文件的过程中转向执行目标文件,两个文件(当前文件和目标文件)属于同一次请求,前后页 共用一个request,可以通过此来传递一些数据或者session信息,request.setAttribute()和 request.getAttribute()。

2、在前后两次执行后,地址栏不变,仍是当前文件的地址。

3、不能转向到本web应用之外的页面和网站,所以转向的速度要快。

4、URL中所包含的“/”表示应用程序(项目)的路径。


2. 重定向 response.sendRedirect():

1、属于重定向,也是客户端跳转,相当于客户端向服务端发送请求之后,服务器返回一个响应,客户端接收到响应之后又向服务端发送一次请求,一共是2次请求,前后页不共用一个request,不能读取转向前通过request.setAttribute()设置的属性值。

2、在前后两次执行后,地址栏发生改变,是目标文件的地址。

3、可以转向到本web应用之外的页面和网站,所以转向的速度相对要慢。

4、URL种所包含的"/"表示根目录的路径。


  特殊的应用:对数据进行修改、删除、添加操作的时候,应该用response.sendRedirect()。如果是采用了 request.getRequestDispatcher().forward(request,response),那么操作前后的地址栏都不会发生 改变,仍然是修改的控制器,如果此时再对当前页面刷新的话,就会重新发送一次请求对数据进行修改,这也就是有的人在刷新一次页面就增加一条数据的原因。

4.  测试

代码如下:

package chat;

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class FirstServlet
 */
@WebServlet("/FirstServlet")
public class FirstServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public FirstServlet() {
        super();
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        System.out.println("=====FirstServlet=====S ");
        System.out.println("request: " + request + "	 response: " + response);
        Enumeration<String> parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()) {
            String nextElement = parameterNames.nextElement();
            System.out.println("key: " + nextElement + ", value: " + request.getParameter(nextElement));
        }

        String beforeDispatch = "FirstServlet BeforeDispatch";
        response.getWriter().write(beforeDispatch);
        System.out.println(beforeDispatch);

        request.getRequestDispatcher("/SecondServlet?addParam=newParam").forward(request, response);
        // response.sendRedirect("/WebSocket/SecondServlet?addParam=newParam");

        String afterDispatch = "FirstServlet AfterDispatch";
        response.getWriter().write(afterDispatch);
        System.out.println(afterDispatch);

        System.out.println("=====FirstServlet=====E ");
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}
package chat;

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class FirstServlet
 */
@WebServlet("/SecondServlet")
public class SecondServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public SecondServlet() {
        super();
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        System.out.println("=====SecondServlet=====S ");
        System.out.println("request: " + request + "	 response: " + response);
        Enumeration<String> parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()) {
            String nextElement = parameterNames.nextElement();
            System.out.println("key: " + nextElement + ", value: " + request.getParameter(nextElement));
        }

        String dispose = "SecondServlet dispose";
        response.getWriter().write(dispose);

        System.out.println("=====SecondServlet=====E ");
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

1. 测试转发:

注释掉上面重定向代码,访问:http://localhost:86/WebSocket/FirstServlet?addParam=newParam

 

java控制台结果:

=====FirstServlet=====S
request: org.apache.catalina.connector.RequestFacade@123810d1 response: org.apache.catalina.connector.ResponseFacade@1ed812af
key: name, value: zs
FirstServlet BeforeDispatch
=====SecondServlet=====S
request: org.apache.catalina.core.ApplicationHttpRequest@175ea12f response: org.apache.catalina.connector.ResponseFacade@1ed812af
key: name, value: zs
key: addParam, value: newParam
=====SecondServlet=====E
FirstServlet AfterDispatch
=====FirstServlet=====E

2. 测试重定向

注释掉转发代码,访问http://localhost:86/WebSocket/FirstServlet?addParam=newParam

java控制台代码:

=====FirstServlet=====S
request: org.apache.catalina.connector.RequestFacade@123810d1 response: org.apache.catalina.connector.ResponseFacade@1ed812af
key: name, value: zs
FirstServlet BeforeDispatch
FirstServlet AfterDispatch
=====FirstServlet=====E
=====SecondServlet=====S
request: org.apache.catalina.connector.RequestFacade@123810d1 response: org.apache.catalina.connector.ResponseFacade@1ed812af
key: addParam, value: newParam
=====SecondServlet=====E

原文地址:https://www.cnblogs.com/qlqwjy/p/7445269.html