轉發與重定向的區別詳解
我們知道,在servlet中呼叫轉發、重定向的語句如下:
<span style="font-size:18px;">request.getRequestDispatcher("test.jsp").forward(request,response); //轉發到test.jsp
response.sendRedirect("test.jsp"); //重定向到test.jsp</span>
在jsp頁面中你也會看到通過下面的方式實現轉發:
<jsp:forward page=" test.jsp" />
當然也可以在jsp頁面中實現重定向:
<%response.sendRedirect("test.jsp");%> //重定向到test.jsp
解釋一:從工作原理上分析
一句話,轉發是伺服器行為,重定向是客戶端行為。為什麼這樣說呢,這就要看兩個動作的工作流程:
請求轉發(RequestDispatcher)的過程
客戶首先發送一個請求到伺服器端,伺服器端發現匹配的servlet,並指定它去執行,當這個servlet執行完之後,它要呼叫getRequestDispacther()方法,把請求轉發給指定的test.jsp,整個流程都是在伺服器端完成的,而且是在同一個請求裡面完成的,因此servlet和jsp共享的是同一個request,在servlet裡面放的所有東西,在jsp中都能取出來,因此,jsp能把結果getAttribute()出來,getAttribute()出來後執行完把結果返回給客戶端。整個過程是一個請求,一個響應。
重定向(sendRedirect)的工作原理:
客戶傳送一個請求到伺服器,伺服器匹配servlet,這都和請求轉發一樣,servlet處理完之後呼叫了sendRedirect()這個方法,這個方法是response的方法,所以,當這個servlet處理完之後,看到response.senRedirect()方法,立即向客戶端返回這個響應,響應行告訴客戶端你必須要再發送一個請求,去訪問test.jsp,緊接著客戶端受到這個請求後,立刻發出一個新的請求,去請求test.jsp,這裡兩個請求互不干擾,相互獨立,在前面request裡面setAttribute()的任何東西,在後面的request裡面都獲得不了。可見,在sendRedirect()裡面是兩個請求,兩個響應。
解釋二:從表面理解
1、重定向,其實是兩次request第一次,客戶端request A,伺服器響應,並response回來,告訴瀏覽器,你應該去B。這個時候IE可以看到地址變了,而且歷史的回退按鈕也亮了。重定向可以訪問自己web應用以外的資源。在重定向的過程中,傳輸的資訊會被丟失.例子:
response.sendRedirect("loginsuccess.jsp");
2、請求轉發是伺服器內部把對一個request/response的處理權,移交給另外一個對於客戶端而言,它只知道自己最早請求的那個A,而不知道中間的B,甚至C、D。傳輸的資訊不會丟失。
例子:
RequestDispatcherdis=request.getRequestDispatcher(“loginsuccess.jsp”);
Dis.forward(request,response);
轉發:
1.轉發不會改變瀏覽器的位址列
2.轉發共享同一個request
3.轉發只能在同一個web應用中使用
重定向:
1.重定向會改變瀏覽器的位址列
2.重定向不共享request
3.可以重定向到任意URL
解釋三:從生活方面理解
重定向過程好比有個綽號叫“瀏覽器”的人寫信找張三借錢,張三回信說沒有錢,讓“瀏覽器”去找李四借,並將李四現在的通訊地址告訴給了“瀏覽器 ”。
於是,“瀏覽器”又按張三提供通訊地址給李四寫信借錢,李四收到信後就把錢匯給了“瀏覽器”。可見,“瀏覽器”一共發出了兩封信和收到了兩次回覆,“ 瀏覽器”也知道他借到的錢出自李四之手。 RequestDispatcher.forward 方法在伺服器端內部將請求轉發給另外一個資源,瀏覽器只知道發出了請求並得到了響應結果,並不知道在伺服器程式內部發生了轉發行為。
這個過程好比綽號叫“ 瀏覽器”的人寫信找張三借錢,張三沒有錢,於是張三找李四借了一些錢,甚至還可以加上自己的一些錢,然後再將這些錢匯給了“瀏覽器”。
可見,“瀏覽器”只發出了一封信和收到了一次回覆,他只知道從張三那裡借到了錢,並不知道有一部分錢出自李四之手。