原作者:向右奔跑
原博客鏈接:Java請求轉(zhuǎn)發(fā)和重定向的區(qū)別
一锈颗、請求轉(zhuǎn)發(fā)和重定向
1)請求轉(zhuǎn)發(fā):
request.getRequestDispatcher(URL地址).forward(request, response)
處理流程:
客戶端發(fā)送請求抹蚀,Servlet做出業(yè)務(wù)邏輯處理慧瘤。
Servlet調(diào)用forword()方法,服務(wù)器Servlet把目標資源返回給客戶端瀏覽器搜吧。
2)重定向:
response.sendRedirect(URL地址)
處理流程:
客戶端發(fā)送請求相速,Servlet做出業(yè)務(wù)邏輯處理沿腰。
Servlet調(diào)用response.sendReadirect()方法,把要訪問的目標資源作為response響應(yīng)頭信息發(fā)給客戶端瀏覽器事哭。
客戶端瀏覽器重新訪問服務(wù)器資源xxx.jsp漫雷,服務(wù)器再次對客戶端瀏覽器做出響應(yīng)。
以上兩種情況鳍咱,你都需要考慮Servlet處理完后珊拼,數(shù)據(jù)如何在jsp頁面上呈現(xiàn)。圖例是請求流炕、響應(yīng)的流程澎现,沒有標明數(shù)據(jù)如何處理、展現(xiàn)每辟。
二剑辫、轉(zhuǎn)發(fā)和重定向的路徑問題
1)使用相對路徑在重定向和轉(zhuǎn)發(fā)中沒有區(qū)別
2)重定向和請求轉(zhuǎn)發(fā)使用絕對路徑時,根/路徑代表了不同含義
重定向response.sendRedirect("xxx")是服務(wù)器向客戶端發(fā)送一個請求頭信息渠欺,由客戶端再請求一次服務(wù)器妹蔽。/指的Tomcat的根目錄,寫絕對路徑應(yīng)該寫成"/當前Web程序根名稱/資源名" 。如"/WebModule/login.jsp","/bbs/servlet/LoginServlet"
轉(zhuǎn)發(fā)是在服務(wù)器內(nèi)部進行的挠将,寫絕對路徑/開頭指的是當前的Web應(yīng)用程序胳岂。絕對路徑寫法就是"/login.jsp"或"/servlet/LoginServlet"。
總結(jié): 以上要注意是區(qū)分是從服務(wù)器外的請求舔稀,還在是內(nèi)部轉(zhuǎn)發(fā)乳丰,從服務(wù)器外的請求,從Tomcat根寫起(就是要包括當前Web的根)内贮;是服務(wù)器內(nèi)部的轉(zhuǎn)發(fā)产园,很簡單了,因為在當前服務(wù)器內(nèi)夜郁,/寫起指的就是當前Web的根目錄什燕。
三、轉(zhuǎn)發(fā)和重定向的區(qū)別
request.getRequestDispatcher()是容器中控制權(quán)的轉(zhuǎn)向竞端,在客戶端瀏覽器地址欄中不會顯示出轉(zhuǎn)向后的地址屎即;服務(wù)器內(nèi)部轉(zhuǎn)發(fā),整個過程處于同一個請求當中。
response.sendRedirect()則是完全的跳轉(zhuǎn)技俐,瀏覽器將會得到跳轉(zhuǎn)的地址乘陪,并重新發(fā)送請求鏈接。這樣虽另,從瀏覽器的地址欄中可以看到跳轉(zhuǎn)后的鏈接地址暂刘。不在同一個請求。重定向捂刺,實際上客戶端會向服務(wù)器端發(fā)送兩個請求谣拣。
所以轉(zhuǎn)發(fā)中數(shù)據(jù)的存取可以用request作用域:request.setAttribute(), request.getAttribute()
,重定向是取不到request中的數(shù)據(jù)的族展。只能用session森缠。forward()更加高效,在可以滿足需要時仪缸,盡量使用RequestDispatcher.forward()方法贵涵。(思考一下為什么?)
RequestDispatcher是通過調(diào)用HttpServletRequest對象的getRequestDispatcher()方法得到的恰画,是屬于請求對象的方法宾茂。
sendRedirect()是HttpServletResponse對象的方法,即響應(yīng)對象的方法拴还,既然調(diào)用了響應(yīng)對象的方法跨晴,那就表明整個請求過程已經(jīng)結(jié)束了,服務(wù)器開始向客戶端返回執(zhí)行的結(jié)果片林。重定向可以跨域訪問端盆,而轉(zhuǎn)發(fā)是在web服務(wù)器內(nèi)部進行的,不能跨域訪問费封。