1. 程式人生 > >Servlet頁面跳轉技術--重定向、轉發和包含

Servlet頁面跳轉技術--重定向、轉發和包含

**

Servlet頁面跳轉技術(Java)

重定向RequestDispatcher和轉發httpServletResponse.sendRedirect是javaEE中很常見的頁面跳轉技術,當我們在處理一個程式需要在後臺跳轉頁面的時候。我們就要用到頁面跳轉技術。
兩種跳轉技術的應用場合:

  • 重定向RequestDispatcher既可以應用於跳轉到站外(專案的外面),也可以應用於專案內的跳轉。如果非要專案之間(站外)進行跳轉,那麼必須要選擇重定向技術,重定向可以在站外進行(如果是站外路徑要帶“http://”開頭,站內路徑要帶專案名);
  • 轉發只能在站內(專案內跳轉),路徑預設在專案內,即路徑不用帶專案名.

請求:類(javax.servlet.RequestDispatcher)

在某種情況下,一個Servlet類可能無法完成全部的工作,為了讓各Servlet協同工作,Servlet規範為Web元件之間協同工作提供了兩種途徑:
請求轉發。-源元件將請求轉發給目標元件。
請求包含。-源元件將目錄元件的結果包含到自身的響應結果中來。

  • 獲取RequestDispatcher的兩種方法:
         呼叫ServletContext.getRequestDispatcher(path)
         呼叫HttpServletRequest.getRequestDispatcher(path)
         以上兩者的區別在於 (建議使用第二種並使用/開頭)
         前者path引數必須是絕對路徑,即必須以/開頭。
         後者path即可以是絕對路徑,也可以是相對路徑。

請求轉發的處理流程:rd.forward(request, response)

RequestDispatcher rd=request.getRequestDispatcher("/servlet/TwoServlet");
        rd.forward(request, response);//轉發內容仍然儲存在改頁面中

1、清空用於存放響應正文資料的緩衝區。
也正因此,源元件在轉發之前的內容不會被髮送的客戶端。
2、如果目標元件為Servlet、Jsp就呼叫它們的Service方法。如果目標元件為html頁面,就讀取此文字將它傳送到客戶端。
3、關閉輸出流。
也正因此,源元件在呼叫之後傳送的文字不會被髮送的客戶端。

請求轉發知識點:
轉發:傳參,訪問順序(doGet還是doPost) —轉發是共享同一個request和同一個response物件的
1)第一個是doGet,第二個走的也是doGet
2)第一個是doPost,第二個走的也是doPost
3)傳參:可以通過request.setAttribute()設定,通過request.getAttribute()獲取 —doGet或doPost都一樣
4)後面程式碼不會執行

請求包含的處理特點如下:
相當於一段程式碼中嵌入一個方法(其他程式碼)
1、如果目標元件為Servlet或jsp就呼叫它的service方法。如果是html頁面就直接將結果內容新增到源元件的響應結果中。
2、再返回到源元件中繼續執行後續的程式碼。
3、在目標元件中設定的響應頭將會被忽略。
4、如果在目錄元件中關閉了輸出流,則源元件後面的輸出將不會輸出到客戶端。
程式碼示例:

RequestDispatcher rd=request.getRequestDispatcher("/servlet/Include2Servlet");
rd.include(request, response);

請求包含知識點:
請求包含:傳參,訪問順序(doGet還是doPost)
1)兩個servlet的輸出都有效!—中途呼叫flush,流不會關閉,後續的輸出都會執行。如果在第一個servlet中執行了out.close(),那麼後續的輸出(無論是第一還是第二個servlet)都不會執行,但程式不會出異常!!!!
2)第一個是doGet,第二個走的也是doGet
3)第一個是doPost,第二個走的也是doPost
4)對於請求包含,第二個servlet在執行完之後,還會回到第一個servlet的rd.include()這行程式碼之後。
5)傳參方面,和轉發是完全一樣的,因為都是共享同一個request和同一個response.
6)後面程式碼繼續執行

重定向

程式碼

response.sendRedirect(“somepage”);

重要細節:
重定向是瀏覽器自動又向伺服器發起的新請求。所以不會共享之前的request和response對像。
重定向:傳參,訪問順序(doGet還是doPost)
1)無論第一個是doGet還是doPost,第二個走的都是doGet
2)傳參:第二個servlet中的request和第一個是完全不同的物件,因此無法通過:request.setAttribute()和request.getAttribute() 實現傳參。
3)第二個servlet中是無法通過request.getParameter()的方式獲取頁面提交的引數資料
4)重定向方式下,如果要進行傳參,可採用:在位址列的url後新增類似如下的格式傳參:?name=Jack&age=23response.sendRedirect(request.getContextPath()+"/servlet/Redir2Servlet?name=Jack&age=10");
注意,採用位址列url傳參的方式,在瀏覽器位址列是能夠看到的,因此要注意隱私(安全)問題—如果有隱私引數,那麼要加密!!!
5)轉發只能在站內進行(路徑預設在專案內,即路徑不用帶專案名),重定向可以在站外進行(如果是站外路徑要帶“http://”開頭,站內路徑要帶專案名)。如果非要專案之間(站外)進行跳轉,那麼必須要選擇重定向。

包含

請求包含:傳參,訪問順序(doGet還是doPost)
1)兩個servlet的輸出都有效!—中途呼叫flush,流不會關閉,後續的輸出都會執行。如果在第一個servlet中執行了out.close(),那麼後續的輸出(無論是第一還是第二個servlet)都不會執行,但程式不會出異常!!!!
2)第一個是doGet,第二個走的也是doGet
3)第一個是doPost,第二個走的也是doPost
4)對於請求包含,第二個servlet在執行完之後,還會回到第一個servlet的rd.include()這行程式碼之後。
5)傳參方面,和轉發是完全一樣的,因為都是共享同一個request和同一個response.
6)頁面輸出時,注意html標籤不要輸出衝突,如:在第一個servlet中輸出了“”和“”,同時在第二個servlet中也輸出這些標記。這樣會出現html標記巢狀衝突!!