2013-06-13 73 views
5

爲簡單起見,這些代碼片段將會縮短。這樣做的目的是獲取一個GET參數,將其設置在會話中,並在刪除url參數的情況下重定向回GET。基本上,URI清理。如果有更好/更簡單的方法來做到這一點,我會很高興聽到它。爲什麼SessionAttributes在GET重定向時被清除?

我有定義爲這樣的控制器:

@Controller 
@RequestMapping("/path/page.xhtml") 
@Scope(BeanDefinition.SCOPE_PROTOTYPE) 
@SessionAttributes({ "myParam1", "myParam2" }) 
public class MyController { 

    @RequestMapping(method = RequestMethod.GET, params = { "urlParam2" }) 
    public String handleUriParam(@RequestParam(value = "urlParam2", required = false) 
           final Long urlParam2, 
           final RedirectAttributes redirs) { 
    // at this point, myParam1 is set on the session. 
    // now set the param as a flash attrib with the name of the session variable 
    redirs.addFlashAttribute("myParam2", urlParam2); 
    return "redirect:/path/page.xhtml"; 
    } 

    @RequestMapping(method = RequestMethod.GET, params = {}) 
    public String doGetStuff(ModelMap model) { 
    // do stuff using myParam1 and myParam2. 
    // problem is, myParam2 is on the session, but myParam1 is not! 
    } 

} 

像代碼說,不知何故myParam1正在取消集時重定向發生。我可以通過將ModelMap傳遞給handleUrlParam方法並手動將myParam1添加到Flash屬性來解決此問題,但這似乎破壞了我的想法。

爲什麼在重定向後SessionAttributemyParam1被刪除?

是否有更好的方法從URI中提取參數並將它們放在會話中?

UPDATE

如此看來,只要您使用RedirectAttributes可言,你必須確保你把你想帶入的FlashAttributes重定向,否則他們將失去任何SessionAttribute秒。我想象會發生這種情況,因爲SessionAttribute被從ModelMap拉下來(使用時被FlashAttributes取代)。這是Spring中的一個錯誤還是故意的行爲?如果這是故意的,有人可以解釋爲什麼?我認爲SessionAttribute是爲了繼續下去,直到通過完成對話會議而被刪除。

Similar StackOverflow post here

附錄

在提供的接受的答案來看,我仍然難倒,同時將它們放入用戶的會話我如何清除URI參數。我考慮過的一個選項是爲半原始對象(java.lang.Integer,java.lang.String)創建一個包裝器,因爲它們不會放在URI字符串上,所以我試圖存儲它,但是這似乎很難我。如果有人有更好的方法來接受GET參數,將它們存儲在用戶的會話中,並清除用戶地址欄中的內容(這將需要重定向),我會很樂意使用它。

+0

我不知道你在做什麼錯,但我剛剛複製了你的配置,它按預期工作。這兩個屬性都以會話結束(這對於第二個屬性來說可能很奇怪,因爲它應該是flash屬性)。 –

+0

奇數。我基本上放棄和設置兩個Flash屬性,它工作正常。它有點違背了使用'@ SessionAttribute'的目的,但是對於常規的'GET'請求,它按預期工作。感謝您的關注。 – Andy

+0

我剛剛想到的一點是,不同於大多數人的配置是使用'BeanDefinition.SCOPE_PROTOTYPE'。你有沒有使用它,仍然得到正確的行爲?我很好奇,如果創建/使用新的控制器對象可能成爲問題的一部分。由於我們的攔截器和控制器結構,我們必須使用新鮮的物體,但這只是一個想法,是否可能是我的怪異行爲的責任。 – Andy

回答

5

所以我在環顧代碼和互聯網,找出它爲什麼不起作用。

Spring有兩個完全獨立的模型映射 - 一個用於標準視圖渲染,另一個用於發佈重定向。這可以在ModelAndViewContainer中觀察到。

現在會話屬性持久性已完成based on the result from mavContainer#getModel()。對於重定向方案,這將返回重定向模型。因此,無論您在標準Model/ModelMap上設置什麼,都會丟失。

當談論標準模型屬性時,這是有道理的。模型主要用於將對象傳遞給視圖。使用重定向時,您正在處理完全不同的情況。你想通過HTTP重定向傳輸對象 - 因此分開的字符串和基於閃存的模型。

但是我的感覺是他們忘記了會話屬性designing this feature。有一些不錯的discussion in Spring's Jira,但是他們都沒有解決這個具體問題。

因此,這可能是Spring的Jira的一個主題。而它可能被歸類爲bug,因爲這可以防止任何人在使用重定向時設置會話模型屬性。強制Spring通過RedirectAttributes#addFlashAttribute存儲會話屬性是IMO自身的一種攻擊和種類

+0

雖然我同意你的評論是黑客,但我仍然需要從用戶的地址欄中清除URI參數。有沒有比我目前正在嘗試這樣做的「黑客」方式做得更少? – Andy

+0

另外,感謝您對此進行調查。你的解釋非常徹底,非常合理。 :) – Andy

相關問題