一、兩種跳轉(zhuǎn)獲得對象的方式
1??獲得轉(zhuǎn)發(fā)對象getRequestDispatcher()
httpServletRequest.getRequestDispatcherServletContext.getRequestDispatcher();
2??獲得重定向?qū)ο髎endRedirect()
httpServletResponse.sendRedirect();
二早龟、區(qū)別
-
RequestDispatcher.forward (轉(zhuǎn)發(fā))
只能將請求轉(zhuǎn)發(fā)給同一個Web應(yīng)用中的組件案疲;而HttpServletResponse.sendRedirect (重定向)
不僅可以重定向到當(dāng)前應(yīng)用程序中的其他資源祝沸,還可以重定向到同一個站點上的其他應(yīng)用程序中的資源矮烹,甚至是使用絕對URL重定向到其他站點的資源。如果傳遞給HttpServletResponse.sendRedirect (重定向)
方法的相對URL以“/”開頭罩锐,它是相對于整個Web站點的根目錄奉狈;如果創(chuàng)建RequestDispatcher對象時指定的相對URL以“/”開頭,它是相對于當(dāng)前Web應(yīng)用程序的根目錄涩惑。 - 調(diào)用
RequestDispatcher.forward (轉(zhuǎn)發(fā))
的請求過程結(jié)束后仁期,瀏覽器地址欄保持初始的URL地址不變;而調(diào)用HttpServletResponse.sendRedirect (重定向)
的訪問過程結(jié)束后,瀏覽器地址欄中顯示的URL會發(fā)生改變跛蛋,由初始的URL地址變成重定向的目標(biāo)URL熬的。 -
HttpServletResponse.sendRedirect (重定向)
對瀏覽器的請求直接作出響應(yīng),響應(yīng)的結(jié)果就是告訴瀏覽器去重新發(fā)出對另外一個URL的訪問請求赊级⊙嚎颍可以這樣理解,假設(shè)你去辦理某個執(zhí)照:
【重定向】你先去了A局理逊。A局的人說:“這個事情不歸我們管橡伞,你得去B局”。然后晋被,你就從A局退了出來兑徘,自己又去了B局。
RequestDispatcher.forward (轉(zhuǎn)發(fā))
在服務(wù)器端內(nèi)部將請求轉(zhuǎn)發(fā)給另外一個資源羡洛,瀏覽器只知道發(fā)出了請求并得到了響應(yīng)結(jié)果挂脑,并不知道在服務(wù)器程序內(nèi)部發(fā)生了轉(zhuǎn)發(fā)行為。還是辦理執(zhí)照:
【轉(zhuǎn)發(fā)】你先去了A局翘县,A局看了以后最域,知道這個事情實際應(yīng)該B局來管,但是他沒有把你退回來锈麸,而是讓你等一會兒,自己到后面辦公室聯(lián)系了B的人牺蹄,讓他們辦好后忘伞,送了過來。你只知道事情辦好了沙兰,卻不知道實際辦理的是另一個局的人氓奈。
-
RequestDispatcher.forward (轉(zhuǎn)發(fā))
的調(diào)用者與被調(diào)用者之間共享相同的request對象和response對象,它們屬于同一個訪問請求和響應(yīng)過程鼎天。轉(zhuǎn)發(fā)2次跳轉(zhuǎn)之間傳輸?shù)男畔⒉粫G失舀奶。
而HttpServletResponse.sendRedirect (重定向)
調(diào)用者與被調(diào)用者使用各自的request對象和response對象,它們屬于兩個獨立的訪問請求和響應(yīng)過程斋射。重定向2次跳轉(zhuǎn)之間傳輸?shù)男畔G失(request范圍)育勺。
對于同一個Web應(yīng)用程序的內(nèi)部資源之間的跳轉(zhuǎn),特別是跳轉(zhuǎn)之前要對請求進(jìn)行一些前期預(yù)處理罗岖,并要使用HttpServletRequest.setAttribute
傳遞預(yù)處理結(jié)果涧至,那就應(yīng)該使用RequestDispatcher.forward (轉(zhuǎn)發(fā))
。不同Web應(yīng)用程序之間的重定向桑包,特別是要重定向到另外一個Web站點上的資源的情況南蓬,都應(yīng)該使用HttpServletResponse.sendRedirect (重定向)
。 - 無論是轉(zhuǎn)發(fā),還是重定向赘方,在調(diào)用它們之前烧颖,都不能有內(nèi)容已經(jīng)被實際輸出到了客戶端。如果緩沖區(qū)中已經(jīng)有了一些內(nèi)容窄陡,這些內(nèi)容將被從緩沖區(qū)中清除倒信。
三、轉(zhuǎn)發(fā)和重定向的選擇
- 重定向的速度比轉(zhuǎn)發(fā)慢泳梆,因為瀏覽器還得發(fā)出一個新的請求鳖悠,所以如果在使用轉(zhuǎn)發(fā)和重定向都無所謂的時候建議使用轉(zhuǎn)發(fā)。
- 因為轉(zhuǎn)發(fā)只能訪問當(dāng)前Web的應(yīng)用程序优妙,所以不同Web應(yīng)用程序之間的訪問乘综,特別是要訪問到另外一個Web站點上的資源的情況,這個時候就只能使用重定向了套硼。
注意:
重定向有一個應(yīng)用場景:避免在用戶重新加載頁面時兩次調(diào)用相同的動作卡辰。當(dāng)我們提交產(chǎn)品表單的時候,執(zhí)行保存的方法將會被調(diào)用邪意,并執(zhí)行相應(yīng)的動作九妈。這在一個真實的應(yīng)用程序中,很有可能將表單中的所有產(chǎn)品信息加入到數(shù)據(jù)庫中雾鬼。但是如果在提交表單后,重新加載頁面策菜,執(zhí)行保存的方法就很有可能再次被調(diào)用晶疼,同樣的產(chǎn)品信息就將可能再次被添加。為了避免這種情況又憨,提交表單后蠢莺,你可以將用戶重定向到一個不同的頁面,這樣的話锄弱,這個網(wǎng)頁任意重新加載都沒有副作用棵癣;
但是狈谊,使用重定向的一個不便之處是壁榕,無法將值輕松地傳遞給目標(biāo)頁面。而采用轉(zhuǎn)發(fā)赎瞎,則可以簡單地將屬性添加到Model,使得目標(biāo)視圖可以輕松訪問牌里。由于重定向經(jīng)過客戶端,所以Model中的一切都會在重定向時丟失务甥。但幸運(yùn)的是牡辽,在Spring3.1版本以后,我們可以通過Flash屬性敞临,解決重定向時傳值丟失的問題态辛。
要使用Flash屬性,必須在Spring MVC的配置文件中添加一個挺尿。然后奏黑,還必須在方法上添加一個新的參數(shù)類型:org.springframework.web.servlet.mvc.support.RedirectAttributes。
如下所示:
@RequestMapping(value="saveProduct",method=RequestMethod.POST)
public String saveProduct(ProductForm productForm,RedirectAttributes re){
//執(zhí)行產(chǎn)品保存的業(yè)務(wù)邏輯等
//傳遞參數(shù)
re.addFlashAttribute("message","The product is saved successfully");
//執(zhí)行重定向
return "redirect:/……";
}