1. 程式人生 > >Request請求轉發和重定位的區別

Request請求轉發和重定位的區別

來源:http://blog.csdn.net/chenyi8888/article/details/6947954

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);