zoukankan      html  css  js  c++  java
  • 重定向和转发的区别

    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

  • 相关阅读:
    Android的FileOutputStream中向文本文件中写入换行符
    简单又好看的按钮,扁平化按钮。
    android常见错误之 No resource found that matches the given name
    eclipse中Android模拟器,DDMS看不到设备
    Android软件开发之盘点所有Dialog对话框大合集
    Android软件开发之TextView详解
    frameset网页彻底退出或跳转(转)
    .Net 如何限制用户登录(转)
    将上传图片文件转成二进制流再存储
    数据库链接字符串自动生成
  • 原文地址:https://www.cnblogs.com/qlqwjy/p/7445269.html
Copyright © 2011-2022 走看看