首頁>技術>

一、簡介

二、RequestDispatcher

RequestDispatcher接收客戶端請求,並將它們傳送到server中的其它資源(如servlet、html檔案、JSP檔案)。RequestDispatcher當作對指定路徑或名稱的服務資源的包裝。

2.1 RequestDispatcher獲取

RequestDispatcher是透過HttpServletRequest.getRequestDispatcher方法獲取的,引數為指定的資源路徑,如果路徑是相對路徑,則相對目錄是當前servlet的。HttpServletRequest.getRequestDispatcher方法定義原始碼如下:

public RequestDispatcher getRequestDispatcher(String path);

2.2 原始碼

RequestDispatcher的核心方法是forward和include,這裡把RequestDispatcher中定義的常量也列出來,原始碼如下:

package javax.servlet;

import java.io.IOException;

public interface RequestDispatcher {

static final String FORWARD_REQUEST_URI = "javax.servlet.forward.request_uri";

static final String FORWARD_CONTEXT_PATH = "javax.servlet.forward.context_path";

static final String FORWARD_PATH_INFO = "javax.servlet.forward.path_info";

static final String FORWARD_SERVLET_PATH = "javax.servlet.forward.servlet_path";

static final String FORWARD_QUERY_STRING = "javax.servlet.forward.query_string";

//include方式下,目標請求的URI名稱(值在目標request中attribute中獲取)

static final String INCLUDE_REQUEST_URI = "javax.servlet.include.request_uri";

//include方式下,目標context路徑名稱(值在目標request中attribute中獲取)

static final String INCLUDE_CONTEXT_PATH = "javax.servlet.include.context_path";

//include方式下,目標路徑資訊名稱(值在目標request中attribute中獲取)

static final String INCLUDE_PATH_INFO = "javax.servlet.include.path_info";

//include方式下,目標servlet路徑名稱(值在目標request中attribute中獲取)

static final String INCLUDE_SERVLET_PATH = "javax.servlet.include.servlet_path";

//include方式下,目標查詢串名稱(值在目標request中attribute中獲取)

static final String INCLUDE_QUERY_STRING = "javax.servlet.include.query_string";

//error方式下,傳遞的異常物件名稱(值在目標request中attribute中獲取)

public static final String ERROR_EXCEPTION = "javax.servlet.error.exception";

//error方式下,傳遞的異常型別名稱(值在目標request中attribute中獲取)

public static final String ERROR_EXCEPTION_TYPE = "javax.servlet.error.exception_type";

//error方式下,傳遞的異常資訊名稱(值在目標request中attribute中獲取)

public static final String ERROR_MESSAGE = "javax.servlet.error.message";

//error方式下,導致傳遞異常的請求URI名稱(值在目標request中attribute中獲取)

public static final String ERROR_REQUEST_URI = "javax.servlet.error.request_uri";

//error方式下,傳遞的發生錯誤的servlet名稱(值在目標request中attribute中獲取)

public static final String ERROR_SERVLET_NAME = "javax.servlet.error.servlet_name";

//error方式下,傳遞的響應code名稱(值在目標request中attribute中獲取)

public static final String ERROR_STATUS_CODE = "javax.servlet.error.status_code";

public void forward(ServletRequest request, ServletResponse response)

throws ServletException, IOException;

//在響應請求中新增指定資源(servlet、jsp、html)

public void include(ServletRequest request, ServletResponse response)

throws ServletException, IOException;

}

關聯的Dispatcher型別源,DispatcherType原始碼如下:

package javax.servlet;

public enum DispatcherType {

//透過RequestDispatcher.forward方法請求

FORWARD,

//透過RequestDispatcher.include方法請求

INCLUDE,

//正常請求

REQUEST,

//非同步請求

ASYNC,

//錯誤響應

ERROR

}

2.3.1 forward

graph LR

browser --1請求--> oneServlet

twoServlet --3響應--> browser

2.3.2 include

include是在處理客戶端請求時,同時新增其它server資源(servlet、jsp、html)的響應,瀏覽器地址不會改變。流程示意如下:

graph LR

browser --1請求--> oneServlet

twoServlet --3響應--> oneServlet

oneServlet --4響應--> browser

2.3.3 sendRedirect

sendRedirect是位於HttpServletResponse中的方法,是直接將使用者請求重置,由瀏覽器再次發起請求,瀏覽器地址會改變。流程示意圖如下:

graph LR

browser --1請求--> oneServlet

oneServlet --2響應--> browser

browser --3再次主動--> twoServlet

twoServlet --4再次響應--> browser

三、示例

請求1的OneServlet.java定義如下:

package requestDispatcher;

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.util.Objects;

@WebServlet(name="oneServlet", urlPatterns = "/oneServlet")

public class OneServlet extends HttpServlet {

@Override

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

resp.getWriter().write("this is oneServlet. ");

String type = Objects.toString(req.getParameter("type"), "redirect");

RequestDispatcher requestDispatcher = req.getRequestDispatcher(req.getContextPath()+"/twoServlet");

if("forward".equals(type)){

requestDispatcher.forward(req, resp);

}else if("include".equals(type)){

requestDispatcher.include(req, resp);

}else {

resp.sendRedirect(req.getContextPath()+"/twoServlet");

}

}

}

請求2的TwoServlet.java定義如下:

package requestDispatcher;

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;

@WebServlet(name="twoServlet", urlPatterns = "/twoServlet")

public class TwoServlet extends HttpServlet {

@Override

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

Object originServletPath = req.getAttribute(RequestDispatcher.FORWARD_PATH_INFO);

System.out.println("originServletPath:"+originServletPath);

resp.getWriter().write("this is towServlet.");

}

}

操作結果:

請求:http://localhost:8080/oneServlet?type=forward

響應:this is towServlet.

請求:http://localhost:8080/oneServlet?type=include

響應:this is oneServlet. this is towServlet.

請求:http://localhost:8080/oneServlet?type=redirect

響應:his is towServlet.

同時:瀏覽器地址變為 http://localhost:8080/twoServlet

25
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • servlet中事件監聽相關原始碼解析