zoukankan      html  css  js  c++  java
  • 请求包含(Include)和请求转发(Forward)

    定义

      请求包含是指将另一个Servlet的请求处理流程包含进来。
      请求转发是指将请求转发给别的Servlet处理。


    实现

      实现请求包含和请求转发,可以使用HttpServletRequest的getRequestDispatcher()方法取得RequestDispatcher接口的实现对象实例,调用时传入请求、响应对象即可。
      取得RequestDispatcher还有两个方式,通过ServletContext的getRequestDispatcher()或getNamedDispatcher()。


    demo

    package com.test;
    
    import javax.servlet.RequestDispatcher;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.PrintWriter;
    
    @WebServlet({"/some.controller", "/world"})
    public class Some extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            PrintWriter out = response.getWriter();
            out.println("Some do one...");
            RequestDispatcher dispatcher = request.getRequestDispatcher("other.view");
            // 请求包含
            dispatcher.include(request, response);
            // 请求转发
            // dispatcher.forward(request, response);
            out.println("Some do two...");
        }
    }
    Some.java
    package com.test;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.util.Arrays;
    
    @WebServlet({"/other.view", "/view"})
    public class Other extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
    
            response.getWriter().println("Other do one...");
        }
    }
    Other.java

    请求转发 forward 的响应结果是:

      Other do one...

    请求包含 include 的响应结果是:

      Some do one...
      Other do one...
      Some do two...


    区别

      forward:目前的Servlet不能有任何响应确认,如果在目前的Servlet中通过响应对象设置了一些响应但未确认(响应缓冲区未满或未调用任何清除方法),则所有响应设置会被忽略,如果已经有响应确认且调用了forward()方法,则会抛出IllegalStateException。

      include:被包含的Servlet中任何对请求标头的设置都会被忽略。但被包含的Servlet中可以使用getSession()方法取得HttpSession对象。


    相同点

    1、在取得RequestDispatcher时,也可以包括查询字符串。
      例如:req.getRequestDispatcher("other.view?data=123456").include(req, resp);
      这样在被包含或转发的Servlet中就可以使用getParameter("data")取得请求参数值。
    2.查询字符串的方式,仅适用于传递字符串值给另一个Servlet;如果有必须共享的“对象”,可以设置给请求对象成为属性。
      HttpServletRequest上与请求范围属性有关的几个方法如下。
      setAttribute():指定名称与对象设置属性。
      getAttribute():指定名称取得属性。
      getAttributeNames():取得所有属性名称。
      removeAttribute():指定名称移除属性。

    example:

    package com.test;
    
    import javax.servlet.RequestDispatcher;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.PrintWriter;
    
    @WebServlet({"/some.controller", "/world"})
    public class Some extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            request.setAttribute("setAttr", new int[]{1, 2, 3});
    
            PrintWriter out = response.getWriter();
            out.println("Some do one...");
            RequestDispatcher dispatcher = request.getRequestDispatcher("other.view?data=123456");
            // 请求包含
            // dispatcher.include(request, response);
            // 请求转发
            dispatcher.forward(request, response);
            out.println("Some do two...");
        }
    }
    Some.java
    package com.test;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.util.Arrays;
    
    @WebServlet({"/other.view", "/view"})
    public class Other extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
    
            String data = request.getParameter("data");
            int[] getAttr = (int[])request.getAttribute("setAttr");
    
            response.getWriter().println("Other do one..." + " | "
                    + "include or forward parameter: " + data + " | "    // 请求或转发时携带的查询参数
                    + "setAttrbute object: " + Arrays.toString(getAttr));  // 共享对象
        }
    }
    Other.java

    请求转发 forward 的响应结果是:

      Other do one... | include or forward parameter: 123456 | setAttrbute object: [1, 2, 3]

    请求包含 include 的响应结果是:

      Some do one...
      Other do one... | include or forward parameter: 123456 | setAttrbute object: [1, 2, 3]
      Some do two...


    相似点

    javax.servlet.

    include.request_uri

    javax.servlet.

    include.context_path

    javax.servlet.

    include.servlet_path

    javax.servlet.

    include.path_info

    javax.servlet.

    include.query_string

    javax.servlet.

    forward.request_uri

    javax.servlet.

    forward.context_path

    javax.servlet.

    forward.servlet_path

    javax.servlet.

    forward.path_info

    javax.servlet.

    forward.query_string

    Servlet

    Request URI Context path Servlet path Path info

    取得RequestDispatcher时

    给定的查询参数

    如果被包含或转发的Servlet还包含或转发其他的Servlet,则这些属性名称的对应值也会被代换。

    example:

    package com.test;
    
    import javax.servlet.RequestDispatcher;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.PrintWriter;
    
    @WebServlet({"/some.controller", "/world"})
    public class Some extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            PrintWriter out = response.getWriter();
            out.println("Some do one...");
            RequestDispatcher dispatcher = request.getRequestDispatcher("other.view?data=123456");
            // 请求包含
            dispatcher.include(request, response);
            // 请求转发
            // dispatcher.forward(request, response);
            out.println("Some do two...");
        }
    }
    Some.java
    package com.test;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    @WebServlet({"/other.view", "/view"})
    public class Other extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
    
            String request_uri, context_path, servlet_path, path_info, query_string;
    
            // 默认的请求包含时的参数
            /*request_uri = (String)request.getAttribute("javax.servlet.include.request_uri");
            context_path = (String)request.getAttribute("javax.servlet.include.context_path");
            servlet_path = (String)request.getAttribute("javax.servlet.include.servlet_path");
            path_info = (String)request.getAttribute("javax.servlet.include.path_info");
            query_string = (String)request.getAttribute("javax.servlet.include.query_string");*/
            // 默认的请求转发时的参数
            request_uri = (String)request.getAttribute("javax.servlet.forward.request_uri");
            context_path = (String)request.getAttribute("javax.servlet.forward.context_path");
            servlet_path = (String)request.getAttribute("javax.servlet.forward.servlet_path");
            path_info = (String)request.getAttribute("javax.servlet.forward.path_info");
            query_string = (String)request.getAttribute("javax.servlet.forward.query_string");
    
    
            response.getWriter().println("Other do one..." + " | "
                    + "request_uri: " + request_uri + " | "
                    + "context_path: " + context_path + " | "
                    + "servlet_path: " + servlet_path + " | "
                    + "path_info: " + path_info + " | "
                    + "query_string: " + query_string
            );
        }
    }
    Other.java

    请求转发 forward 的响应结果是:

      Other do one... | request_uri: /hello/some.controller | context_path: /hello | servlet_path: /some.controller | path_info: null | query_string: null

    请求包含 include 的响应结果是:

      Some do one...
      Other do one... | request_uri: /hello/other.view | context_path: /hello | servlet_path: /other.view | path_info: null | query_string: data=123456
      Some do two...

  • 相关阅读:
    BZOJ 4032: [HEOI2015]最短不公共子串 (dp*3 + SAM)
    后缀自动机详解!
    BZOJ 3926: [Zjoi2015]诸神眷顾的幻想乡(广义后缀自动机 多串)
    BZOJ 3938 Robot
    [JSOI2008]Blue Mary开公司
    [ZJOI2017]树状数组
    [JSOI2015]非诚勿扰
    [HNOI2011]任务调度
    BZOJ 3680 吊打XXX
    POJ 3318 Matrix Multiplication
  • 原文地址:https://www.cnblogs.com/Mike_Chang/p/10033063.html
Copyright © 2011-2022 走看看