在說請求轉發和重定向之前,得了解下JSP九大內置對象中的response和request
response:將服務器端數據發送到客戶端,可通過在客戶端瀏覽器中顯示,用戶瀏覽頁面的重定向以及在客戶端創建Cookies等實現;
重定向:response.setRedirect(url) (把響應發送到另一個指定的頁面進行處理)。
request:可以對在客戶請求中給出的信息進行訪問,包含了所有有關當前瀏覽器的請求信息。
請求轉發:request.getRequestDispatcher(url).forward(request,response)。
差異:
1. 請求的次數:
重定向比請求轉發多請求一次,下面以例子說明。
如果現在有一個需求:A首先向B發出請求,然后B再向C發出請求。
先看重定向方式(B->C):首先A向B發出請求(第一次),然后B通過重定向的方式跳轉到C,但不會直接向C發出請求,而是先返回到A,通過A向C發出請求(第二次),具體看下面這張圖。
然后看請求轉發方式(B->C):首先A向B發出請求(第一次),然后B通過請求轉發的方式跳轉到C,這就不會通過A來跳轉,而是B自己直接向C發出請求,具體看下面這張圖。
2.地址欄是否改變:(還是以上面的A.jsp,B.jsp,C.jsp為例)
如果現在A要請求B,然后B要請求C。
先看重定向方式:首先在瀏覽器地址欄輸入http://localhost:8080/test/A.jsp (8080是我自己的端口號,test是工程名)
然后A會跳轉到B,此時的地址就是http://localhost:8080/test/B.jsp
最后由B跳轉到C,地址為http://localhost:8080/test/C.jsp (第二次請求,A跳轉到C,所以地址會發生改變)
再看請求轉發方式:首先在瀏覽器地址欄輸入http://localhost:8080/test/A.jsp
然后A會跳轉到B,此時的地址就是http://localhost:8080/test/B.jsp
最后由B跳轉到C,地址為http://localhost:8080/test/B.jsp (僅僅是服務器的內部跳轉,所以地址會不會改變)
3.是否保留第一次請求時的數據:
再說保留數據之前,先復習一下4種范圍對象:pageContext,request,session,application(范圍越來越大,造成的性能損耗也越大,所以盡量使用最小的)
這四種范圍對象有幾個很重要的共同的方法:(無論是重定向還是請求轉發都要使用到 setAttribute來賦值 和 getAttribute來取值,只不過前者是session調用並且用session來取得數據,后者是request調用並且用request取得數據)
- Object getAttribute(String name);//根據屬性名返回屬性值,注意返回類型
- void setAttribute(String name,Object obj);//根據屬性名設置屬性值,如果沒有改屬性,則新建一個屬性,然后賦值
- void removeAttribute(string name);//根據屬性名刪除屬性值
- pageContext:僅僅是當前頁面有效(只要跳轉了,就失效,null),下方的代碼就會輸出world
1 <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> 2 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 3 <html> 4 <head> 5 <title>test</title> 6 </head> 7 <body> 8 <% 9 pageContext.setAttribute("hello", "world"); 10 %> 11 12 <%=pageContext.getAttribute("hello")%> 13 </body> 14 </html>
- request:同一次請求有效(比如請求轉發,就是同一次請求,而重定向屬於兩次請求),下方的代碼就是通過請求轉發的方式傳送數據,也就是說請求轉發會保存數據(即使B.jsp再次跳轉到其他頁面,通過request還是可以取到數據)
1 <!-- A.jsp --> 2 <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 4 <html> 5 <head> 6 <title>test</title> 7 </head> 8 9 <body> 10 <% 11 request.setAttribute("hello", "world"); 12 request.getRequestDispatcher("B.jsp").forward(request,response); 13 %> 14 15 </body> 16 </html>
1 <!-- B.jsp --> 2 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 4 <html> 5 <head> 6 </head> 7 8 <body> 9 <%=request.getAttribute("hello")%> 10 </body> 11 </html>
但如果利用重定向的方式跳轉到B.jsp,將不會把數據傳過去,但如果還是想用重定向,可以利用下面這個內置對象session
- session:同一次會話有效(只要瀏覽器不關,都屬於同一次會話,無論是重定向還是請求轉發,都有效;關閉或切換瀏覽器后無效;),session是存在於服務器端的,所以如果使用重定向的方式跳轉,可以利用session來獲取數據(並不是重定向傳了數據,而是獲取了服務器端的數據)
1 <!--A.jsp --> 2 <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 4 <html> 5 <head> 6 <title>test</title> 7 </head> 8 9 <body> 10 <% 11 session.setAttribute("hello", "world"); 12 response.sendRedirect("B.jsp"); 13 %> 14 </body> 15 </html>
1 <!-- B.jsp --> 2 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 4 <html> 5 <head> 6 </head> 7 <body> 8 <%=session.getAttribute("hello")%> 9 </body> 10 </html>
- application:全局變量,整個項目運行期間都有效(瀏覽器切換仍然有效,但關閉瀏覽器后在啟動瀏覽器是無效的),但只對當前項目有效(其他項目是無法訪問的)此處不貼代碼。
該筆記如有錯誤,還請斧正。