SpringMVC入門之十一:跨重定向請求傳遞資料
通常,當我們處理完POST請求之後,出於安全的考慮(防止使用者重新整理或後退而重新執行危險的POST請求),會將請求重定向,在前面,我們藉助了“redirect:”來實現這一功能。”redirect:”字首能夠讓重定向功能變得非常簡單,但是Spring為重定向功能還提供了一些其他的輔助功能。具體來講,正在發起重定向功能的方法該如何傳送資料給重定向的目標方法呢?一般來講,當一個處理器方法完成之後,該方法所指定的模型資料將會複製到請求中,並作為請求中的屬性,請求會轉發(forward)到檢視上進行渲染。因為控制器方法和檢視所處理的是同一個請求,所以在轉發過程中,請求屬效能夠得到儲存。 但是,當控制器的結果是重定向的話,原始的請求就結束了,並且會發起一個新的GET請求。原始請求中所帶有的模型資料也就隨著請求一起消亡了。在新的請求屬性中,沒有任何的模型資料,這個請求必須要自己計算資料。(模型的屬性是以請求屬性的形式存放在請求中的,在重定向後無法存活) 顯然,對於重定向來說,模型並不能用來傳遞資料。但是我們也有一些其他方案,能夠從發起重定向的方法傳遞資料給處理重定向方法中:
-
a、使用URL模板以路徑變數和/或查詢引數的形式傳遞資料;
-
b、通過flash屬性發送資料
下面的程式清單展現瞭如何通過路徑變數和查詢引數來向重定向請求傳遞資料:
{username}佔位符會匹配model中的username屬性,而spitterId沒有能夠匹配的佔位符,則會以查詢引數的形式傳遞。如果username屬性的值是habuma並且spitterId屬性的值是42,那麼結果得到的重定向URL路徑將會是“/spitter/habuma?spitterId=42”。在上面的程式碼中,雖然用到了模型,但是模型資料最終是以請求引數的形式複製到請求中的,當重定向發生的時候,這些資料就會丟失。 通過路徑引數和查詢引數的方式來為重定向請求傳遞引數非常簡單,
當我們不想在重定向請求中傳送username或ID了,而是要傳送實際的Spitter物件,那麼通過URL模板已經不能滿足要求了。也許將這些資料放到會話中是個可行的方案,實際上在JSP+Servlet開發專案的時候就是這麼做的,但是這要求我們在請求重定向之前將屬性裝Session中,重定向成功過後還要將這個屬性移除,這也許不是什麼大不了的事兒。不過,Spring認為我們並不需要管理這些資料,相反,Spring提供了將資料傳送為flash屬性的功能。按照定義,flash屬性會一直攜帶這些資料直到下一次請求,然後才會消失。 Spring提供了通過RedirectAttribute設定flash屬性的方法,這是Spring3.1引入的Model的一個子介面。RedirectAttribute提供了Model的所有功能,除此之外,還有幾個方法是用來設定flash屬性的。具體來講,RedirectAttribute提供了一組addFlashAttribute()方法來新增flash屬性。重新看一下processRegistration()方法,
在這裡,我們呼叫了addFlashAttribute()方法,並將spitter作為key,Spitter物件作為值。另外,我們還可以不設定key引數,讓key根據值的型別自行推斷得出:
flash屬性傳遞引數的原理:在重定向執行之前,所有的flash屬性都會複製到會話中。在重定向後,存在會話中的flash屬性會被取出,並從會話轉移到模型中。