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

    转载

     

    请求重定向和转发

    1、请求重定向:浏览器的行为(通过响应对象HttpServletResponse来执行)

    特点:可以重新定向访问其他Web应用下的资源

    浏览器发出了2次请求,得到了2次响应

    地址栏地址会变,跳转到要求指定的Servlet

    代码演示:

    //请求重定向方式一:

    public void sent1(HttpServletResponse response) {
    
    response.setStatus(302);
    
    response.setHeader("Location", "/ServletStudy/servlet/ServletDemo2");
    
    //这个地址是要求浏览器重新访问的。
    
    }

    //请求重定向方式二:

    public void send2(HttpServletRequest request,HttpServletResponse response) 
    
    throws IOException {
    
    //服务器向访问的浏览器的请求中添加属性,当被请求重定向后,在新的Servlet中不能得到添加的属性。
    
    //因为请求重定向后的请求request对象不懂,这就是request的生命周期。
    
    request.setAttribute("name", "zhangsan");
    
     
    
    //与方式一实现的原理相同,较为常用
    
    response.sendRedirect("/ServletStudy/servlet/ServletDemo2");
    
    }

     

    2、请求转发:服务器的行为(转发的瞬间是一个ServletRequest的生命周期)

    特点:转发只能发生在当前Web应用下

    浏览器发出了1次请求,得到了1次响应

    (源组件和目标组件共享request和response中的数据)

    地址栏地址不会发生变化。

    应用:

    (1)可以利用request的域对象的特点,由源组件向其中存放写数据。

    (2)可以让用户访问到存放在WEB-INF目录中的目标资源

    代码演示:

    //请求转发
    
    public void send3(HttpServletRequest request,HttpServletResponse response) 
    
        throws ServletException, IOException{
    
    //在请求转发之前进行属性添加,在新的Servlet资源中能获取这个属性
    
    request.setAttribute("name", "zhangsan");
    
    //获取当前Servlet资源的转发器对象RequestDispatcher,传入当前应用的下要访问的那个Servlet资源
    
    RequestDispatcher rd = getServletContext()
    
      .getRequestDispatcher("/servlet/ServletDemo2");
    
     
    
    //注意:传入的要访问的Servlet资源的地址中/代表的就是当前应用,所以就可以访问当前应用中WEB-INF中的信息
    
    rd = getServletContext()
    
       .getRequestDispatcher("/WEB-INF/form.html");
    
     
    
    //也可以通过request得到转发器对象,用request得到的转发器在传入路径时,可以传入相对路径,不用加/
    
    rd = request.getRequestDispatcher("/servlet/ServletDemo2");
    
    //这里传入的路径地址:相对去被转发地址不同地方
    
    //被转发地址:
    
    http://localhost:8080/ServletStudy/servlet/ServletDemo1
    
    //转发地址:
    
    http://localhost:8080/ServletStudy/servlet/ServletDemo2
    
    //所以填写相对资源地址:ServletDemo2
    
     
    
    rd = request.getRequestDispatcher("ServletDemo2");
    
     
    
     
    
    //调用转发器的forward()方法,进行请求转发
    
    rd.forward(request, response);
    
    }
    
     

    3.RequestDispatcher中forward()转发和include()包含的区别

    forword()转发:源组件<--->头+体

    源组件转向目标组件,由目标组件显示响应正文结果(只有目标的响应)

    转发前,容器会清空response对象的缓存,源组件的任何页面输出都无效,也就是会清空源组件的体

    转发前不要刷新或关闭response的流

     

    include()包含:

    源组件包含目标组件,由源组件显示响应正文结果(还会把目标的响应结果包含进来)

    包含前,容器会清空目标组件设置的响应头信息,目标组件所有设置的所有头都无效。

    代码演示:

    //RequestDispatch转发器中的:forward()和include()方法的区别

    /*forword()转发:

    源组件转向目标组件,由目标组件显示响应结果(只有目标的响应)

    转发前,容器会清空response对象的缓存,源组件的任何页面输出都无效。

    转发前不要刷新或关闭response的流

     

    include()包含:

    源组件包含目标组件,由源组件显示响应结果(还会把目标的响应结果包含进来)

    包含前,容器会清空目标组件设置的响应头信息,目标组件所有设置的所有头都无效*/

    public class ServletDemo3 extends HttpServlet {
    
    //当做源组件
    
    public void doGet(HttpServletRequest request, HttpServletResponse response)
    
    throws ServletException, IOException {
    
    forwardTest(request, response);
    
    }
    
     
    
    public void forwardTest(HttpServletRequest request,
    
    HttpServletResponse response) throws IOException, ServletException {
    
    //response.setHeader("Refresh", "2");
    
    OutputStream out = response.getOutputStream();
    
    System.out.println("转发前向控制台输出");
    
    out.write("转发前向页面输出".getBytes());
    
    RequestDispatcher rd = request.getRequestDispatcher("ServletDemo4");
    
    rd.forward(request, response);
    
    System.out.println("转发后向控制台输出");
    
    out.write("转发后向页面输出".getBytes());
    
    }
    
     
    
    public class ServletDemo4 extends HttpServlet {
    
    //当做目标组件
    
    public void doGet(HttpServletRequest request, HttpServletResponse response)
    
    throws ServletException, IOException {
    
    response.setHeader("Refresh", "2");
    
    response.getOutputStream().write("目标组件".getBytes());
    
     
    
    }

     

     

    4.ServletContext和ServletRequest都能得到RequestDispatcher区别

    (1)ServletContext

    RequestDispatcher getRequestDispatcher(String path):path必须以"/"开头,代表当前的应用。这种写法,叫做绝对路径写法。

    (2)ServletRequest

    RequestDispatcher getRequestDispatcher(String path):

    path可以以"/"开头:代表当前的应用。这种写法,叫做绝对路径写法。

    也可以不以"/"开头:代表相对路径。

     

    5.各种URL的写法:绝对路径和相对路径,建议大家使用绝对路径

    绝对路径:如:/day05  地址前加了/就是一个绝对路径

    原则:要不要加应用名称,看地址为谁服务的?

    如果是给服务器用的,就不用加/MyApp,"/"代表的是当前应用。

    如果是给客户端用的,要加上"/MyApp","/"代表的是要访问的服务器的URL地址(域名+端口),

    getRequestDispatcher(String path):

    path是一个路径。 不要加"/MyApp",只需要"/"即可

    form action="url":要加"/MyApp"

    a href="url":要加"/MyApp"

    img src="url":要加"/MyApp"

    link href="url":要加"/MyApp"

    script src="url":要加"/MyApp"

    302+Location="url":要加"/MyApp"

     

  • 相关阅读:
    题解 UVA120 【煎饼 Stacks of Flapjacks】
    信息编码表示

    二叉树
    逻辑运算&位运算
    POJ2425 Ubiquitous Religions(并查集板题)
    CF1426E Rock, Paper, Scissors 题解
    POJ2478 Farey Sequence
    dubbo+zookeeper报错 KeeperErrorCode = Unimplemented for /dubbo
    代码无法提交到GitHub: Remote URL test failed: git@github.com: Permission denied (publickey)
  • 原文地址:https://www.cnblogs.com/shaoxiaohuan/p/7660979.html
Copyright © 2011-2022 走看看