天天看點

請求轉發與請求重定向一. 請求轉發的細節二. 請求轉發與請求重定向三. 請求轉發與請求重定向的差別四. 執行個體

一. 請求轉發的細節

1. forward方法用于将請求轉發到RequestDispatcher對象封裝的資源。

2. 如果在調用forward方法之前,在Servlet程式中寫入的部分内容已經被真正地傳送到了用戶端,forward方法

将抛出IllegalStateException異常。 

3. 如果在調用forward方法之前向Servlet引擎的緩沖區中寫入了内容,隻要寫入到緩沖區中的内容還沒有被真正

輸出到用戶端,forward方法就可以被正常執行,原來寫入到輸出緩沖區中的内容将被清空,但是,已寫入到

HttpServletResponse對象中的響應頭字段資訊保持有效。

二. 請求轉發與請求重定向

1. 請求轉發

一個web資源收到用戶端請求後,通知伺服器去調用另外一個web資源進行處理,稱之為請求轉發。

2. 請求重定向

一個web資源收到用戶端請求後,通知浏覽器去通路另外一個web資源,稱之為請求重定向。

三. 請求轉發與請求重定向的差別

1. 差別:

(1) RequestDispatcher.forward方法隻能将請求轉發給同一個WEB應用中的元件;而

HttpServletResponse.sendRedirect 方法還可以重定向到同一個站點上的其他應用程式中的資源,甚至是使用

絕對URL重定向到其他站點的資源。 

(2) 如果傳遞給HttpServletResponse.sendRedirect 方法的相對URL以“/”開頭,它是相對于整個WEB站點的

根目錄;如果建立RequestDispatcher對象時指定的相對URL以“/”開頭,它是相對于目前WEB應用程式的根目

錄。 

(3) 調用HttpServletResponse.sendRedirect方法重定向的通路過程結束後,浏覽器位址欄中顯示的URL會發生

改變,由初始的URL位址變成重定向的目标URL;調用RequestDispatcher.forward 方法的請求轉發過程結束

後,浏覽器位址欄保持初始的URL位址不變。

(4) HttpServletResponse.sendRedirect方法對浏覽器的請求直接作出響應,響應的結果就是告訴浏覽器去重新

發出對另外一個URL的通路請求;RequestDispatcher.forward方法在伺服器端内部将請求轉發給另外一個資

源,浏覽器隻知道發出了請求并得到了響應結果,并不知道在伺服器程式内部發生了轉發行為。 

(5) RequestDispatcher.forward方法的調用者與被調用者之間共享相同的request對象和response對象,它們屬

于同一個通路請求和響應過程;而HttpServletResponse.sendRedirect方法調用者與被調用者使用各自的

request對象和response對象,它們屬于兩個獨立的通路請求和響應過程。 

2. 總結:

(1) 轉發

① 位址欄不會改變;  

② 轉發隻能轉發到目前web應用内的資源;

③ 在轉發過程中,可以把資料儲存到request域對象中;

(2) 重定向

① 位址欄會改變,變成重定向到的位址;

② 重定向可以跳轉到目前web應用,或其他web應用,甚至是外部域名網站;

③ 在重定向的過程,不能把資料儲存到request域對象中。

注意:如果要使用request域對象進行資料共享,隻能用轉發技術。

四. 執行個體

1. 執行個體

(1) ForwardDemo1

/*
 * 轉發(效果:跳轉頁面)
 */
@WebServlet("/ForwardDemo1")
public class ForwardDemo1 extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		/*
		 * 儲存資料到request域對象
		 */
		request.setAttribute("name", "Jack");
		/*
		 * 注意:不能轉發到目前web應用以外的資源
		 */
		/*
		RequestDispatcher rd = this.getServletContext().getRequestDispatcher("/GetDateServlet");
		rd.forward(request, response);
		*/
		this.getServletContext().getRequestDispatcher("/GetDateServlet").forward(request, response);//注釋内容的簡寫
	}
}
           

(2) RedirectDemo1

/*
 * 重定向
 */
@WebServlet("/RedirectDemo1")
public class RedirectDemo1 extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		/*
		 * 儲存資料到request域對象
		 */
		request.setAttribute("name", "Rose");
		// 重定向
		/*
		 * 注意:可以跳轉到web應用内或其他web應用,甚至其他外部域名。
		 */
		response.sendRedirect("/zw_Servlet/GetDateServlet");
	}
}
           

(3) GetDateServlet

@WebServlet("/GetDateServlet")
public class GetDateServlet extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		/*
		 * 從request域對象中擷取資料
		 */
		String name = (String) request.getAttribute("name");
		System.out.println("name=" + name);
	}
}
           

2. 運作結果

請求轉發與請求重定向一. 請求轉發的細節二. 請求轉發與請求重定向三. 請求轉發與請求重定向的差別四. 執行個體

3. 存在的問題與解決

(1) 疑問:為什麼通路ForwardDemo1的時候可以讀取出name=Jack,而通路RedirectDemo1的時候卻讀取出

name=null?

(2) 分析:

請求轉發與請求重定向一. 請求轉發的細節二. 請求轉發與請求重定向三. 請求轉發與請求重定向的差別四. 執行個體

tomcat伺服器中有轉發ForwardDemo1和重定向RedirectDemo1,它們都要跳轉到GetDataServlet。

①當使用者通路ForwardDemo1的時候,轉發的原理是:

使用者發送request對象給ForwardDemo1,而ForwardDemo1把request對象轉發給目标資源GetDateServlet,

轉發是伺服器内部的行為,轉發的這個request對象和使用者發送的request對象是同一個對象而在

ForwardDemo1中儲存了資料,儲存的資料放在了request對象中去,把資料發到另外一個Servlet中,那麼另外

一個Servlet是可以拿到這個資料的。因為是同一個請求。

②當使用者通路RedirectDemo1的時候,重定向的原理是:

當使用者發送請求request給RedirectDemo1,那麼RedirectDemo1先進行資料儲存,然後立刻發送一個響應給用

戶,響應的内容是302+location,接着使用者請求GetDateServlet,這個GetDateServlet再傳回一個響應給用

戶。但是我們是在GetDateServlet中去拿出資料,而第二次的請求和第一次的請求是完全不同的請求對象,是以

第一次存的資料,第二次根本拿不了。

4. 總結:

在轉發的過程中,可以把資料存放到request域對象中去,但是在重定向的過程中,不能把資料存放到request域

對象中去。

繼續閱讀