區別一:
重新導向時瀏覽器上的網址改變
轉寄是瀏覽器上的網址不變
區別二:
重新導向實際上產生了兩次請求
轉寄只有一次請求
重新導向:
發送請求 -->伺服器運行-->響應請求,返回給瀏覽器一個新的地址與響應碼-->瀏覽器根據響應碼,判定該響應為重新導向,自動發送一個新的請求給伺服器,請求地址為之前返回的地址-->伺服器運行-->響應請求給瀏覽器
轉寄:
發送請求 -->伺服器運行-->進行請求的重新設定,例如通過request.setAttribute(name,value)-->根據轉寄的地址,擷取該地址的網頁-->響應請求給瀏覽器
區別三:
重新導向時的網址可以是任何網址
轉寄的網址必須是本網站的網址
詳解:
重新導向:以前的request中存放的變數全部失效,並進入一個新的request範圍。
轉寄:以前的request中存放的變數不會失效,就像把兩個頁面拼到了一起。
本文開始:
先是看上去不同,他們的調用分別如下:
request.getRequestDispatcher("apage.jsp").forward(request, response);//轉寄到apage.jsp
response.sendRedirect("apage.jsp");//重新導向到apage.jsp
在jsp頁面中你也會看到通過下面的方式實現轉寄:
<jsp:forward page="apage.jsp" />
我在初學jsp的時候,對這兩個概念非常模糊,看別人的例子的時候,也是一頭霧水,不知道什麼時候該用哪個。希望下面的解說能對你有所協助。
提到轉寄和重新導向就不得不提到request範圍。很多初學者都知道當我們提交一個表單時,就建立了一個新的請求。實際上,當我們點擊一個連結時,也建立了一個新的請求。那麼一個請求的作用於到底有多大呢?例如:
在頁面a.jsp中有一個連結<a href="b.jsp?id=1">這是指向b的一個連結,而且還帶了一個參數</a>。當我們點擊這個串連的時候,就產生了一個請求,為了明確起見,我們把它叫做requestA->B。現在,在b.jsp頁面中我們就可以從這個請求中擷取資訊了。在b.jsp中你可以寫入out.println(request.getParameter("id"))進行測試。下面更複雜一點,我們在b.jsp頁面中增加下面的語句:
request.setAttribute("name","funcreal");
out.println(request.getAttriblute("name"));//成功顯示了name變數的值。
現在在b.jsp中再增加一個連結:<a href="c.jsp?age=23">這是指向c的一個連結,而且還帶了一個參數</a>,當我們點擊這個串連的時候,將產生一個新的請求,這時requestA-B也就安息了,新的請求叫做requestB-C。同樣的道理,在c.jsp中,我們可以訪問到的變數只有age,因為id,name這兩個變數都屬於requestA-B,此時他已經不存在了。下面是原始碼:
a.jsp
<%@ page contentType="text/html; charset=GBK" %>
<html>
<body bgcolor="#ffffff">
<a href="b.jsp?id=1">指向b.jsp,而且還帶了一個參數id=1。requestA-B現在誕生了</a>
</body>
</html>
b.jsp
<%@ page contentType="text/html; charset=GBK" %>
<html>
<body bgcolor="#ffffff">
<%
out.println("id=" + request.getParameter("id"));
request.setAttribute("name","Func Real");
out.println("name=" + request.getAttribute("name"));
%>
<a href="c.jsp?age=23">requestA-B已經結束了。指向c.jsp,而且還帶了一個參數age=23</a>
</body>
</html>
c.jsp
<%@ page contentType="text/html; charset=GBK" %>
<html>
<body bgcolor="#ffffff">
<%
out.println("id=" + request.getParameter("id"));
out.println("name=" + request.getAttribute("name"));
out.println("age=" + request.getParameter("age"));
%>
</body>
</html>
那麼轉寄又是怎麼回事呢?現在增加一個頁面叫做d.jsp,並且在c.jsp中</body>前面增加一句<jsp:forward page="d.jsp"/>
d.jsp
<%@ page contentType="text/html; charset=GBK" %>
<html>
<body bgcolor="#ffffff">
requestB-C的魔爪已經伸到了d.jsp頁面
<%
out.println("age=" + request.getParameter("age"));
%>
</body>
</html>
運行程式,你會發現c頁面中的內容沒有顯示出來,因為forward是自動執行的,地址欄中雖然是c.jsp但實際上,但瀏覽器中顯示的已經是d.jsp的內容了,而且看到了從b.jsp傳過來的參數。你可以簡單得這樣理解:轉寄,就是延長了requestB-C的範圍,<jsp:forward page="d.jsp"/>,這一句話實際上是把c.jsp和d.jsp粘到了一起,他們就像是在一個頁面中。
如果你用過struts,那麼你就知道為什麼在Action中,最後一句幾乎總是mapping.findForward("xxx");了。因為我們在這個Action中設定的請求範圍的變數都將會在下一個頁面(也許是另一個Action)中用到,所以要用轉寄。
總結:
用重新導向和轉寄不是一個習慣問題。而是什麼情況下必須用什麼的問題。