一、轉發(fā)
轉發(fā)的原理,可以通過下圖展示:
瀏覽器的請求發(fā)送給組件1,組件1經過一些處理之后,將request和response對象“傳遞”給組件2,由組件2繼續(xù)處理,然后輸出響應(當然,也可以繼續(xù)向其他組件“傳遞”),這個傳遞的過程稱之為“轉發(fā)”。整個過程只涉及一次瀏覽器和服務器之間的“請求-響應”,轉發(fā)過程中的組件共享同一個請求(request)和響應(response)對象。
轉發(fā)的意義在于可以實現組件的“分工”。在基于MVC,多層結構的Web應用中,經常需要多個組件協同完成一次“請求-響應”工作,例如:用戶要獲取“設備列表信息”,提交請求至控制器組件(Servlet),該Servlet調用適當的JavaBean獲取了“設備列表”數據然后再轉發(fā)至JSP組件去顯示信息。
RequestDispatcher對象封裝了轉發(fā)操作。通過request的getRequestDispatcher(String path)方法獲得RequestDispatcher對象,其中String類型參數path表示要轉發(fā)到的地址。調用Dispacther對象的forward(request, response)方法實現轉發(fā)。關于轉發(fā)的具體操作,有如下幾點需要注意:
1、轉發(fā)只能在同一個應用的組件之間進行,不可以轉發(fā)給其他應用的地址。
2、轉發(fā)的地址可以用“相對地址”方式,也可以用“絕對地址”方式。但需要注意的是:用絕對地址方式時,應從應用名后(Context path)開始。例如:要轉發(fā)到的地址為: http://192.168.5.100/tst/jsp/somewhere.jsp (其中tst為應用名),對應的絕對地址為:“/jsp/somewhere.jsp”。這是很好理解的,因為轉發(fā)只能轉到本應用內的地址,所以絕對地址是沒有必要包含應用名的。
3、組件之間通過轉發(fā)來分工協作,勢必涉及數據的傳遞,可以通過request對象傳遞數據。request對象的setAttribute和getAttribute分別用于以“名稱-對象對”的形式存取數據。例如:
request.setAttribute("food", "roast duck");
RequestDispatcher rd = request.getRequestDispatcher("jsp/somewhere.jsp");
rd.forward(request, response);
somewhere.jsp的內容:
<h1>Hey, <%=request.getAttribute("food")%></h1>
在轉發(fā)之前通過request的setAttribute(String name,Object obj)方法向request中存入了一個名為“food”的字符串對象“roast duck”。在轉發(fā)到的jsp/somewhere.jsp中可以通過request的方法
getAttribute方法取出名為“food”的對象,然后顯示在頁面上。
4、在一個組件轉發(fā)給另外一個組件之前,通過response輸出的響應內容是沒有意義的。例如:在下面的語句中:
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<h2>head</h2><hr/>");
RequestDispatcher rd = request.getRequestDispatcher("jsp/somewhere.jsp");
rd.forward(request, response);
用戶看到的是/jsp/somewhere.jsp的內容,而在轉發(fā)之前的通過out對象輸出的內容:
"<h2>head</h2><hr/>" 最終不會輸出到瀏覽器,這是由于RequestDispatcher在轉發(fā)之前清空了輸出緩沖區(qū)。但如果在轉發(fā)之前輸出的信息超出了緩沖區(qū),或者調用了out對象的flush()方法,此響應內容已經輸出到了客戶端(稱之為響應信息已提交),此時如果實施轉發(fā)操作會拋出運行時異常:java.lang.IllegalStateException。
二、重定向
重定向的含義可以由下圖說明:
瀏覽器向某組件發(fā)出請求信息,組件向瀏覽器發(fā)回一個重定向響應信息,該響應信息不包含具體的數據內容,只是在響應頭信息中包含了需要重定向到的地址信息,該地址可以是任何有效的URL。瀏覽器收到該重定向響應后會自動的向響應信息頭中所指示的地址發(fā)出請求。整個重定向的過程涉及兩次“請求-響應”。具體的重定向響應格式如下所示:
HTTP/1.1 302 Moved Temporarily
Server: Apache-Coyote/1.1
Location: http://192.168.5.100:8080/tst/jsp/somewhere.jsp
Content-Length: 0
Date: Mon, 30 Jun 2008 03:52:54 GMT
注意:重定向響應中包含重定向地址的部分。
重定向可以通過response的sendRedirect(String url)方法來實現,注意String類型的參數url表示重定向到的地址,需要注意的是,如果表示重定向到本應用內的一個絕對地址時,要從應用名前開始,例如:tst應用中的某個組件要重定向到本應用內的/jsp/somewhere.jsp,則重定向的絕對地址應該是:“/tst/jsp/somewhere.jsp”這一點和轉發(fā)中的絕對地址表示是不同的。

