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