request對象實現請求轉寄:請求轉寄指一個web資源收到用戶端請求後,通知伺服器去調用另外一個web資源進行處理。
//request實現請求轉寄,請求轉寄應用情境:mvc設計模式
//重點:在mvc設計模式下,servlet產生資料了之後,如何把資料交給jsp顯示
String data = "aaaa";
request.setAttribute("data", data); //設定屬性
request.getRequestDispatcher("/index.jsp").forward(request, response); //轉寄其實就是傳遞對象
1.request對象提供了一個getRequestDispatcher方法,該方法返回一個RequestDispatcher對象,調用這個對象的forward方法可以實現請求轉寄。
2.request對象同時也是一個域對象,開發人員通過request對象在實現轉寄時,把資料通過request對象帶給其它web資源處理。
request擁有這些方法:setAttribute方法 getAttribute方法 removeAttribute方法 getAttributeNames方法
二.Tip:請求轉寄的細節
forward方法用於將請求轉寄到RequestDispatcher對象封裝的資源。
1.如果在調用forward方法之前,在Servlet程式中寫入的部分內容已經被真正地傳送到了用戶端,forward方法將拋出IllegalStateException異常。
//小心:如果在跳轉之前,資料已經寫給客戶,意味著響應已經完成的情況下,再作轉寄,將會拋異常
//小心,在跳轉之前,寫給瀏覽器的資料是無效的
response.setCharacterEncoding("UTF-8"); //設定伺服器碼錶
response.setContentType("text/html;charset=UTF-8"); //設定瀏覽器開啟碼錶
PrintWriter out = response.getWriter(); //獲得response字元輸出資料流
out.write("aaa"); //將資料寫給瀏覽器,其實是寫到了緩衝中,不關流的話在跳轉之前是無效的,在跳轉後response緩衝中的資訊會清空
//out.close(); //關流後緩衝中的資料會直接寫到瀏覽器上,這個時候再轉寄就會報錯
request.getRequestDispatcher("/index.jsp").forward(request, response); //請求轉寄,但是資料已經寫給了客戶,所以會導致報錯
out.write("bbb"); //輸出資料,在轉寄之後是可以的
2.如果在調用forward方法之前向Servlet引擎的緩衝區(response)中寫入了內容,只要寫入到緩衝區中的內容還沒有被真正輸出到用戶端,forward方法就可以被正常執行,原來寫入到輸出緩衝區中的內容將被清空,但是,已寫入到HttpServletResponse對象中的回應標頭欄位資訊保持有效
三.Tip:請求重新導向和請求轉寄的區別
1.一個web資源收到用戶端請求後,通知伺服器去調用另外一個web資源進行處理,稱之為請求轉寄。
2.一個web資源收到用戶端請求後,通知瀏覽器去訪問另外一個web資源,稱之為請求重新導向。
3.RequestDispatcher.forward方法只能將請求轉寄給同一個WEB應用中的組件;而HttpServletResponse.sendRedirect 方法還可以重新導向到同一個網站上的其他應用程式中的資源,甚至是使用絕對URL重新導向到其他網站的資源。
如果傳遞給HttpServletResponse.sendRedirect 方法的相對URL以“/”開頭,它是相對於整個WEB網站的根目錄;如果建立RequestDispatcher對象時指定的相對URL以“/”開頭,它是相對於當前WEB應用程式的根目錄。
調用HttpServletResponse.sendRedirect方法重新導向的訪問過程結束後,瀏覽器地址欄中顯示的URL會發生改變,由初始的URL地址變成重新導向的目標URL;調用RequestDispatcher.forward 方法的請求轉寄過程結束後,瀏覽器地址欄保持初始的URL地址不變。
4.HttpServletResponse.sendRedirect方法對瀏覽器的請求直接作出響應,響應的結果就是告訴瀏覽器去重新發出對另外一個URL的訪問請求;RequestDispatcher.forward方法在伺服器端內部將請求轉寄給另外一個資源,瀏覽器只知道發出了請求並得到了響應結果,並不知道在伺服器程式內部發生了轉寄行為。
5.RequestDispatcher.forward方法的調用者與被調用者之間共用相同的request對象和response對象,它們屬於同一個訪問請求和響應過程;而HttpServletResponse.sendRedirect方法調用者與被調用者使用各自的request對象和response對象,它們屬於兩個獨立的訪問請求和響應過程。
四.Tip: RequestDispatcher
include方法:
RequestDispatcher.include方法用於將RequestDispatcher對象封裝的資源內容作為當前響應內容的一部分包含進來,從而實現可程式化的伺服器端包含功能。
被包含的Servlet程式不能改變響應訊息的狀態代碼和回應標頭,如果它裡面存在這樣的語句,這些語句的執行結果將被忽略
headservlet.java
response.getWriter().write("header");
footservlet.java
response.getWriter().write("footer");
//用include實現頁麵包含
//獲得轉寄對象調用include方法封裝一個網頭
request.getRequestDispatcher("/servlet/HeadServlet").include(request, response);
String data = "aaa";
//當將data寫出的時候,會先列印網頭,再列印資料,再列印網腳,實現servlet的封裝,方便servlet的調用,在多個請求servlet的時候只需要封裝進來,再改動servlet的時候不用再去一一更改request
response.getWriter().write(data);
//獲得轉寄對象調用include方法封裝一個網腳
request.getRequestDispatcher("/servlet/FootServlet").include(request, response);