1. 程式人生 > >javaEE------------------有關servlet的一些細節(輸出流以及轉發、重定向和請求包含)

javaEE------------------有關servlet的一些細節(輸出流以及轉發、重定向和請求包含)

1.servlet中的兩個輸出流:位元組流(response.getOutputStream()) 和字元流(response.getWriter())

1)用位元組流輸出時,英文可以out.print("Hello1");中文要採用out.write("中文".getBytes())。 對於位元組流,用response.setCharacterEncoding("utf-8")設了也不行。
      2)用字元流輸出時,無論中英文都是:out2.print(); //編碼用 response.setContentType("text/html;charset=utf-8");

3)※※※兩種流不能共存(無論是GET或POST方式提交): 用了位元組流就不能同時用字元,反之亦然!


1)訪問順序:

轉發——第1個POST方式,第2個走的是doPost()。-----該方式下,位址列中最終會顯示成第1個的訪問地址

重定向——無論第1個是GET方式還是POST方式,第2個走的是doGet()。----該方式下,位址列中最終會顯示成第2個的訪問地址

請求包含——第1個GET方式,第2個走的是doGet()。 第1個POST方式,第2個走的是doPost() 頁面內容輸出順序:servlet1..包含之前的輸出...servlet2.....(被包含的servlet輸出)servlet1..包含之後的輸出...

2)讀取頁面引數:

轉發——由於是共享同一個request,請求頁面的引數在兩個servlet當中都可以讀取出來。---請求頁面中,GET方式的引數是在位址列中通過"?name=Jack&age=22"上傳,POST方式是通過<input>元件上傳的。

重定向——由於是不同的request,請求頁面的引數在第1個servlet當中能夠讀取出來,而第2個servlet中不能讀取出來。

請求包含——由於該方式和轉發一樣是共享同一個request和response,因此有關頁面引數讀取和兩個servlet之間的傳參特性,同轉發!

3)兩個servlet之間傳參:

轉發——共享的req和resp,所以可以通過在第一個servlet的service裡給req設定屬性request.setAttribute(),在第二個servle中獲取就好request.getAttribute()。

重定向——“無法”通過  在第1箇中request.setAttribute(),在第2箇中request.getAttribute();  ----通過attribute的路中走不通的,如果非要傳參,可以通過:在第1個servlet當中給重定向地址新增“?name=Jack&age=25”實現---該方式下位址列會顯示引數資訊,明文傳輸資訊,因此敏感資料要加密。

請求包含——由於該方式和轉發一樣是共享同一個request和response,因此有關頁面引數讀取和兩個servlet之間的傳參特性,同轉發!

4)兩個servlet都輸出資訊的問題:

轉發時:1)第一個servlet的輸出資訊只是儲存到快取中,會被第2個servlet清空。因此第1個servlet中的內容無法輸出 2)如果在第1個servlet中呼叫“out.flush();”,那麼第1個servlet中的資訊會輸出,而第2個不會輸出。不但如此,第1個servlet中的轉發都會出異常,因為:刷快取就是要Tomcat幫我們輸出資訊。而同一個請求,Tomcat只會輸出一次,因此輸出之後流就關閉了,無法再轉發。  3)該方式下,位址列中始終顯示的是第1個的訪問地址

重定向是通過response實現的: response.sendRedirect()  第1個servlet中的內容會輸出,但瞬間就會被第2個覆蓋。因為瀏覽器接收到第1個的響應時,立刻會自動發起第2次請求,進而接收並顯示第2次請求的響應結果。 //重定向時的路徑一定要帶專案名稱 ,站外跳轉 只能通過重定向來實現,而且地址必須以“http://”開頭,否則會被識別成站內。

請求包含:通過request實現,與轉發一樣是通過RequestDispatcher,只是前者是rd.forward(req,resp),後者是rd.include(req,resp);在第1個servlet中out.flush(),對兩個servlet的輸出都沒有影響。但如果在第1個servlet中out.close(),則第1個之後的輸出以及第2個servlet中的輸出都無效(不會輸出),注意,後面的rd.include()仍然有效即第2個servlet雖然不能輸出但仍會執行,且沒有異常報出!一個小細節:被包含servlet中的所有輸出資訊(包括<html><body>等標記內容)都會原樣輸出,//因此要注意,兩個servlet之間的輸出內容不要出現標記巢狀衝突! ( 如:<html><body><html><body>...</body></html></body></html>  )

注意:在第1個servlet轉發、重定向或者請求包含程式碼之後,不能再呼叫類似 轉發或重定向 的程式碼。否則會500異常,因為轉發之後,不能再回到此處進行跳轉到別的頁面