請求包含(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...


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM