天天看點

springmvc中使用forward和redirect

本文轉載自“獨釣漁”的部落格

(一) java web程式設計中的forward和redirect

在java web程式設計中跳轉有兩種:” 1:forward ,2:redirect。

我的了解是:forward是請求轉發,redirect是重定向。

forward(請求轉發):

可以看出是統一次請求,當request到達這個servlet後又看到又forward又将目前的request繼續轉發到forward的位址去,在這個過程中,可以利用request.setAttribute設定一些轉發的屬性,都會被帶到目标servlet中去,目标servlet可以通過request.getparam來擷取原始的request請求,也可通過request.getAttribute來擷取轉發過程中的設定的屬性。

redirect(重定向):

redirect重定向,基本可以了解為響應了301,302等之類的,你重新安裝redirect新位址去重新請求。所有一般來說redirect不能帶model資訊,無法像forward利用request.setAttribute來設定一些轉發屬性,如果重定向到外部應用隻有通過GET送出方式傳遞資料,如果是重定向到應用自己内部的其它位址,則還可以利用session實作資料傳遞。

自己總結:

可以了解為forward過程發生在request過程中,redirect發生在response過程中。從浏覽器來看,forward是一次請求,轉發過程在Servlet容器中完成,所有目标Servlet傳回資訊就會在目前的請求response中,浏覽器位址不變;而redirect是重定向,這次請求的servlet響應,響應的response内容為一個redirect, 浏覽器收到這個redirect後重新發起一個新的request請求到redirect這個目标位址,在由這個目标位址的Servlet來響應傳回的内容。也正是應為如此,forward(請求轉發)隻能用在同一個應用中。而redirect可以重定向到其他外部應用中去。

在redirect過程中是一次完全重新的GET請求,如果要在redircet中帶資料轉發隻有這一種方式(利用GET請求時把參數帶上)。

eg1  redirect:/path/list?prama1=values1&prama2=values2

eg2  redirect:http://api.xxx.com/path/list?prama1=values1&prama2=values2           

如果redirect是以/開始這會認為是同一應用中(如eg1),那麼他們直接的資料傳遞還可以利用session實作。

(二) 說說springmvc中的forward和redirect

springmvc完成forward和redirect時本質也是一樣。

Spring MVC 中,我們在傳回邏輯視圖時,架構會通過 viewResolver 來解析得到具體的 View,然後向浏覽器渲染。假設邏輯視圖名為 hello,通過配置,我們配置某個 ViewResolver 如下:

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
    <description>  
        假如邏輯試圖名為 "hello",是以 viewResolver 将解析成 /WEB-INF/jsp/hello.jsp  
    </description>  
    <property name="prefix" value="/WEB-INF/jsp/" />  
    <property name="suffix" value=".jsp" />  
</bean>             

實際上,架構還是通過 forward 的方式轉發到了 /WEB-INF/jsp/hello.jsp。如果邏輯視圖名是 /hello,實際還是轉發到了 /WEB-INF/jsp/hello.jsp,即 /WEB-INF/jsp//hello.jsp 等同于 /WEB-INF/jsp/hello.jsp。

現在有個問題,如果 /hello 就是某個 controller 的映射,我想轉發到這個 controller,怎麼辦?我們可以通過forward 字首來達到轉發到其它資源的目的:

public String handle() {  
    // return "forward:/hello" => 轉發到能夠比對 /hello 的 controller 上  
    // return "hello" => 實際上還是轉發,隻不過是架構會找到該邏輯視圖名對應的 View 并渲染  
    // return "/hello" => 同 return "hello"  
    return "forward:/hello";  
}             

同理,如果我們想重定向到某個資源,我們可以通過 redirect 字首來達到重定向到其它資源的目的:

public String handle() {  
    // 重定向到 /hello 資源  
    return "redirect:/hello";  
}             

forward(請求轉發)因為有request.setAttribute方法是以請求轉發過程中增加一些請求屬性都是非常容易的事情。

redirect(重定向)要想在重定向過程中傳遞資料相對麻煩得多。

1,redirect到外部應用時,隻有通過get送出方式傳遞資料(如eg2)。

2,redircet到應用自己的其它位址時,可以通過get送出方式傳遞資料(如eg1),還可通過session方式傳遞資料。

Spring MVC中有RedirectAttributes類專門用于重定向之後還能帶參數跳轉的的工具類。

他有兩種帶參的方式:

第一種:

redirectAttributes.addAttributie(“prama”,value); 這種方法相當于在重定向連結位址追加傳遞的參數,例如:

redirectAttributes.addAttributie("prama1",value1);
redirectAttributes.addAttributie("prama2",value2);
return:"redirect:/path/list"            

以上重定向的方法等同于 return:”redirect:/path/list?prama1=value1&prama2=value2”

第二種:

redirectAttributes.addFlashAttributie(“prama”,value); 這種方法是隐藏了參數,連結位址上不直接暴露,但是能且隻能在重定向的 “頁面” 擷取prama參數值。其原理就是放到session中,session在跳到頁面後馬上移除對象。如果是重定向一個controller中是擷取不到該prama屬性值的。除非在controller中用(@RequestPrama(value = “prama”)String prama)注解,采用傳參的方式。頁面獲值例如:

redirectAttributes.addFlashAttributie("prama1",value1);
redirectAttributes.addFlashAttributie("prama2",value2);
return:"redirect:/path/list.jsp"
在以上參數均可在list.jsp頁面使用EL表達式擷取到參數值${prama*}
controller獲得redirectAttributes重定向的值例如:

redirectAttributes.addFlashAttributie("prama1",value1);
redirectAttributes.addFlashAttributie("prama2",value2);
return:"redirect:/path/list"

@RequestMapping("list")
public List<Student> list(@RequestPrama(value = "prama1")String  prama1,
   @RequestPrama(value = "prama2")String  prama2,...
){
    //TODO
}           

這可以在controller中擷取redirect傳過來的值。