天天看點

請求轉發和請求包含1、Servlet 容器2、請求轉發和請求包含3、請求轉發(留頭不留體,留體抛異常)4、請求包含(留頭又留體)5、請求轉發和請求包含的比較6、請求轉發的應用:7、請求轉發和重定向的差別  小結:在浏覽器位址欄中輸入某個URL位址或單擊網頁上的一個超連結時,浏覽器發出的HTTP請求消息的請求方式為GET。如果網頁中的<form>表單元素的method屬性被設定為“GET”,浏覽器送出這個FORM表單時生成的HTTP請求消息的請求方式也為GET。

請求轉發和請求包含1、Servlet 容器2、請求轉發和請求包含3、請求轉發(留頭不留體,留體抛異常)4、請求包含(留頭又留體)5、請求轉發和請求包含的比較6、請求轉發的應用:7、請求轉發和重定向的差別  小結:在浏覽器位址欄中輸入某個URL位址或單擊網頁上的一個超連結時,浏覽器發出的HTTP請求消息的請求方式為GET。如果網頁中的<form>表單元素的method屬性被設定為“GET”,浏覽器送出這個FORM表單時生成的HTTP請求消息的請求方式也為GET。

  程式設計中的容器我們可以了解為程式運作時需要的環境,那麼tomcat 就是servlet 的運作環境,就是一個servlet 容器。servlet 容器的作用是負責處理客戶請求,當servlet 容器擷取到使用者請求後,調用某個servlet,并把servlet 的執行結果傳回給使用者。 

  ● 當使用者請求某個資源時,servlet 容器使用servletrequest 對象将使用者的請求資訊封裝起來,然後調用 java servlet api 中定義的servlet

的生命周期方法,完成servlet 的運作。

  ● servlet 容器将servlet 執行後需要傳回使用者的結果封裝到 servletresponse 對象中,最後由servlet 容器發送給客戶,完成對客戶的一次服務過程。

  ● 每一個servlet 都會執行 init()、service()、destory() 三個方法,在啟動時調用一次init) 方法對參數進行初始化,在該servlet 生存期間每當收到對其的請求時都會調用service()

方法對請求進行處理,當容器銷毀時自動調用 destory() 方法對servlet 進行銷毀。 

  正是因為因為servlet 中的service() 方法由servlet 容器調用,是以一個 servlet 的對象是無法調用另一個 servlet 的方法的,但是在實際項目中,對于用戶端請求做出的響應可能會複雜,需要多個servlet 來協作完成,這就需要請求轉發和請求包含技術了。但是,要注意,無論是請求轉發還是請求包含,都是表示由多個servlet

共同處理同一個請求。

  servlet(源元件)先對客戶請求做一些預處理操作(一般是對響應頭進行處理),然後把請求轉發給其他servlet(目标元件)來完成包括生成響應結果在内的後續操作。

  實作方法:request.getrequestdispatcher(“接收請求的servlet 路徑”). forward(request,response)

  getrequestdispatcher(string path):該方法的傳回值類型是requestdispatcher,請求發送器,該方法的參數是指明要接收請求的servlet 的路徑;

  forward(servletrequest req,servletresponse res):該方法是requestdispatcher 接口的方法,将請求從一個 servlet 轉發到伺服器上的另一個資源(servlet、jsp 檔案或 html 檔案)。此方法允許一個 servlet 對請求進行初步處理,并使另一個資源生成響應。需要傳遞兩個參數,這兩個參數是目前servlet 的request 對象和

response 對象傳遞過去的。

  forward() 方法的處理流程:

  ● 清空用于存放響應正文(響應體)資料的緩沖區。

  ● 如果目标元件為servlet 或jsp,就調用它們的service() 方法,把該方法産生的響應結果發送到用戶端,如果目标元件為檔案系統中的靜态 html 文檔,就讀去文檔中的資料并把它發送到用戶端。

  ● 由于 forward() 方法先清空用于存放響應正文資料的緩沖區,是以servlet源元件生成的響應結果不會被發送到用戶端,隻有目标元件生成的結果才會被發送到用戶端,是以對源元件叫“留頭不留體”,目标元件為“留體不留頭”。

  ● 如果源元件在進行請求轉發之前,已經送出了響應結果(例如調用了flush 或close() 方法),那麼forward() 方法會抛出illegalstateexception。為了避免該異常,不應該在源元件中送出響應結果,是以叫留體抛異常。

  servlet(源元件)把其他servlet(目标元件)生成的響應結果包含到自身的響應結果中。

  實作方式:request.getrequestdispatcher(“接收請求的servlet 路徑”). include(request,response)

  include(servletrequest request,servletresponse response):該方法是requestdispatcher 接口的方法,表示包含。它的參數同forward() 方法的參數一樣都是由目前servlet傳遞過去的。

  包含與轉發相比,源元件與被包含的目标元件的輸出資料都會被添加到響應結果中,在目标元件中對響應狀态代碼或者響應頭所做的修改都會被忽略,是以對源元件來說是“留頭又留體”,對目标元件為“留體不留頭”。

  注意:當servlet 源元件調用 requestdispatcher 的 forward 或 include 方法時,都要把目前的 servletrequest 對象和servletresponse 對象作為參數傳給 forward 或 include 方法,這就使得源元件和目标元件共享同一個servletrequest 對象和servletresponse 對象,就實作了多個servlet 協同處理同一個請求。

  requestdispatcher 接口中定義了兩個方法::forward() 方法和 include() 方法,它們分别用于将請求轉發到 requestdispatcher 對象封裝的資源和将 requestdispatcher 對象封裝的資源作為目前響應内容的一部分包含進來.

  aservlet(發送請求方):

  bservlet(接收請求方):

  運作結果為:“我很棒!”(不會輸出“你好!”)。

    對于送出請求的aservlet是:留頭不留體(設定的響應頭可以留下,響應體被接收請求的 bservlet 響應體覆寫); 留體抛異常,就是說隻要請求轉發了,就要将請求完全由 bservlet 處理,aservlet就不能插手了,如果aservlet 也送出了對請求的處理,那麼bservlet 就不能處理請求了(因為請求已經被aservlet 處理了,還處理啥) ,你安排人家處理請求,最終卻由你處理了,當forward() 轉發請求時,發現請求已經被處理,就會抛出異常。

    不過要注意,隻有當aservlet 送出了處理(如例中手動flush将緩沖區内資料送出)才會抛出異常,如果沒有送出,說明之前a對請求的處理還在緩沖區中,b就會直接将a的緩沖區清空,然後覆寫掉,就形成了之前的留頭不留體。

  cservlet(發送請求方):

  dservlet(接收請求方):

  運作結果為:你好!我很棒!

  結果說明請求包含是多個servlet 共同處理一個請求的,并且發送方和接收方都能夠留下響應體。

    請求轉發和請求包含都是在處理一個相同的請求,多個servlet之間使用同一個 request 對象和 response 對象。

    ● 如果在aservlet中請求轉發到bservlet,那麼在aservlet中不允許再輸出響應體,即不能使用response.getwriter() 和response.getoutputstream()

向用戶端輸出,這一工作交由bservlet來完成;如果是由aservlet請求包含bservlet,則沒有這個限制。

    ● 請求轉發不能設定響應體,但是可以設定響應頭,簡單來說就是“留頭不留體”,例如:response.setcontenttype("text/html;charset=utf-8”)

是可以留下來的;請求包含不僅可以設定響應頭,還可以設定響應體,簡單來說就是“留頭又留體“。

    ● 請求轉發大多應用在servlet中,轉發目标大多是jsp頁面;請求包含大多應用在jsp頁面中,完成多頁面的合并。一般情況下經常使用的是請求轉發。

  ● 在servlet中向資料庫擷取資料,儲存到request域中;

  ● 轉發到jsp頁面,jsp從request域中擷取資料,顯示在頁面上。

  ● 對于用戶端浏覽器來說,轉發是一個請求,重定向是兩個請求;

  ● 轉發浏覽器位址欄不變化,重定向會變成轉發後的url ;

  ● 轉發隻能在一個項目内,而重定向沒有限制,可以重定向到任意網址,如京東、淘寶等 ;

  ● 轉發可以使用request 域傳遞資料,而重定向不能。因為轉發是一個請求,重定向是兩個請求;

  ● 轉發隻有一個請求,原來是什麼請求方式就是什麼方式;而重定向兩個請求,第一個可能為post 可能為get ,但是第二個請求一定是get 。

請求轉發和請求包含1、Servlet 容器2、請求轉發和請求包含3、請求轉發(留頭不留體,留體抛異常)4、請求包含(留頭又留體)5、請求轉發和請求包含的比較6、請求轉發的應用:7、請求轉發和重定向的差別  小結:在浏覽器位址欄中輸入某個URL位址或單擊網頁上的一個超連結時,浏覽器發出的HTTP請求消息的請求方式為GET。如果網頁中的<form>表單元素的method屬性被設定為“GET”,浏覽器送出這個FORM表單時生成的HTTP請求消息的請求方式也為GET。