1. 程式人生 > >請求重定向與請求轉發

請求重定向與請求轉發

相信很多剛開始接觸jsp的同學會搞不清楚請求重定向和請求轉發的區別,這裡首先舉個栗子~~

假設你去辦理某個護照

重定向:你去了A局,A局的人說:“這個事不歸我們管,你們應該去B局”,然後,你就從A局退了出來,自己又跑了一趟B局。

請求轉發:你去了A局,A局看了以後,知道這個事情應該歸B局來管,但是他沒有把你的請求退回來,而是讓你坐一會,然後A局到後面自己聯絡了B局的人,把該事情轉手給B局人來 辦,讓他們辦好以後送回A局,然後你的護照就辦理好了。

          分析上面的例子,你是客戶端,你要辦理護照,這是一個request請求,在重定向中,請求頁面是A局,然後A局給你個response,讓你自己再去請求B局,這個時候你自己又傳送 了一次請 求,只不過這次是請求B局,這個重定向是你自己即客戶端的行為,並且是兩次http請求,第一次的請求物件並不會儲存。

          而在請求轉發中,你仍然是客戶端,但是你只發送一次請求,就是向A局傳送了一次http請求,雖然A局自身不能處理你的請求,但是A局把你的request請求物件 轉發給了B局,交給B局來處理,然後再由A局把結果返回給你,這樣你作為客戶端就只有一次請求,請求轉發是伺服器的行為,而且請求轉發是攜帶請求物件,並且在客戶端看來,彷彿是A局處理了你請求。

所以,總結一下就是:

           請求重定向:客戶端行為,response.sendRedirect(),從本質上講等同於兩次請求,前一次請求物件不會儲存,位址列的URL地址會改變

           請求轉發:伺服器端行為,request.getRequestDispatcher().forward(req,resp);是一次請求,轉發請求後物件會儲存,位址列的URL地址不會改變。

下面我們來做個小小的測試

          我們寫三個jsp頁面,一個是register.jsp註冊頁面,裡面有個表單,把使用者名稱密碼提交到handler1,jsp處理頁面。

<form action="handler1.jsp" method="post">
  使用者名稱:<input type="text" name="admin"/>  
  密碼:     <input type="password" name="pswd" />
 <button type="submit">註冊</button>
</form>
       然而,handle1.jsp頁面並不能處理該請求,所以你打算在handle1.jsp裡面進行請求重定向,打算把它交給handler2.jsp進行處理,於是你寫了handler1.jsp是這麼寫的
<% 
   request.setCharacterEncoding("utf-8");
   response.sendRedirect("handler2.jsp");
%>
   那麼你的handler2.jsp是這麼寫的
<%   
   String admin = request.getParameter("admin");
   String pswd = request.getParameter("pswd");
%>
歡迎您,您已註冊成功!!
使用者名稱:<%=admin %>
密碼:<%=pswd %>

      於是你在register.jsp上填寫表單點選註冊按鈕, 你希望的結果是handler2.jsp能夠處理你的請求,在頁面上顯示“歡迎您……使用者名稱:張三,祕密:666”,然後結果卻是

      “歡迎您,註冊成功,使用者名稱:null  密碼:null”

第一張圖片

同時,你會納悶,為什麼在handler2.jsp中獲取不到我的request請求物件 呢???其實,原因很簡單,當你傳送請求至handler1.jsp,它返回給你302,告訴你重定向到handler2.jsp,於是你又傳送一遍請求給handler2.jsp,之前的請求物件根本就沒有傳遞過去。。同時,你也可以在瀏覽器除錯工具中看到,其實是兩次請求

     

所以正確的做法修改handler1.jsp,用請求轉發的方式。

<% 
   request.setCharacterEncoding("utf-8");
   request.getRequestDispatcher("handler2.jsp").forward(request, response);
%>

這樣,你再執行試試就可以得到你想要的結果,你會看到“歡迎您,您已註冊成功!! 使用者名稱:張三 密碼:123"


同時你觀察瀏覽器除錯工具中,會發現確實是一次請求。