一、請求轉(zhuǎn)發(fā)和重定向
請求轉(zhuǎn)發(fā):
request.getRequestDispatcher(URL地址).forward(request, response)
處理流程:
- 客戶端發(fā)送請求,Servlet做出業(yè)務(wù)邏輯處理。
- Servlet調(diào)用forword()方法,服務(wù)器Servlet把目標(biāo)資源返回給客戶端瀏覽器。

2)重定向:
response.sendRedirect(URL地址)
處理流程:
- 客戶端發(fā)送請求,Servlet做出業(yè)務(wù)邏輯處理。
- Servlet調(diào)用response.sendReadirect()方法,把要訪問的目標(biāo)資源作為response響應(yīng)頭信息發(fā)給客戶端瀏覽器。
- 客戶端瀏覽器重新訪問服務(wù)器資源xxx.jsp,服務(wù)器再次對客戶端瀏覽器做出響應(yīng)。

以上兩種情況,你都需要考慮Servlet處理完后,數(shù)據(jù)如何在jsp頁面上呈現(xiàn)。圖例是請求、響應(yīng)的流程,沒有標(biāo)明數(shù)據(jù)如何處理、展現(xiàn)。
二、轉(zhuǎn)發(fā)和重定向的路徑問題
1)使用相對路徑在重定向和轉(zhuǎn)發(fā)中沒有區(qū)別
2)重定向和請求轉(zhuǎn)發(fā)使用絕對路徑時(shí),根/路徑代表了不同含義
重定向response.sendRedirect("xxx")是服務(wù)器向客戶端發(fā)送一個(gè)請求頭信息,由客戶端再請求一次服務(wù)器。/指的Tomcat的根目錄,寫絕對路徑應(yīng)該寫成"/當(dāng)前Web程序根名稱/資源名" 。如"/WebModule/login.jsp","/bbs/servlet/LoginServlet"
轉(zhuǎn)發(fā)是在服務(wù)器內(nèi)部進(jìn)行的,寫絕對路徑/開頭指的是當(dāng)前的Web應(yīng)用程序。絕對路徑寫法就是"/login.jsp"或"/servlet/LoginServlet"。
總結(jié):以上要注意是區(qū)分是從服務(wù)器外的請求,還在是內(nèi)部轉(zhuǎn)發(fā),從服務(wù)器外的請求,從Tomcat根寫起(就是要包括當(dāng)前Web的根);是服務(wù)器內(nèi)部的轉(zhuǎn)發(fā),很簡單了,因?yàn)樵诋?dāng)前服務(wù)器內(nèi),/寫起指的就是當(dāng)前Web的根目錄。
三、轉(zhuǎn)發(fā)和重定向的區(qū)別
request.getRequestDispatcher()是容器中控制權(quán)的轉(zhuǎn)向,在客戶端瀏覽器地址欄中不會顯示出轉(zhuǎn)向后的地址;服務(wù)器內(nèi)部轉(zhuǎn)發(fā),整個(gè)過程處于同一個(gè)請求當(dāng)中。
response.sendRedirect()則是完全的跳轉(zhuǎn),瀏覽器將會得到跳轉(zhuǎn)的地址,并重新發(fā)送請求鏈接。這樣,從瀏覽器的地址欄中可以看到跳轉(zhuǎn)后的鏈接地址。不在同一個(gè)請求。重定向,實(shí)際上客戶端會向服務(wù)器端發(fā)送兩個(gè)請求。
所以轉(zhuǎn)發(fā)中數(shù)據(jù)的存取可以用request作用域:request.setAttribute(), request.getAttribute(),重定向是取不到request中的數(shù)據(jù)的。只能用session。forward()更加高效,在可以滿足需要時(shí),盡量使用RequestDispatcher.forward()方法。(思考一下為什么?)
RequestDispatcher是通過調(diào)用HttpServletRequest對象的getRequestDispatcher()方法得到的,是屬于請求對象的方法。
sendRedirect()是HttpServletResponse對象的方法,即響應(yīng)對象的方法,既然調(diào)用了響應(yīng)對象的方法,那就表明整個(gè)請求過程已經(jīng)結(jié)束了,服務(wù)器開始向客戶端返回執(zhí)行的結(jié)果。重定向可以跨域訪問,而轉(zhuǎn)發(fā)是在web服務(wù)器內(nèi)部進(jìn)行的,不能跨域訪問。