2016-03-22 76 views
8

我有一個Spring-mvc應用程序,並且在每個控制器中,我向SessionAttributes添加一個表單以在保存,刪除或執行另一個獲取請求時保留屬性。當我嘗試在另一個瀏覽器選項卡中打開某個鏈接並嘗試提交第一個鏈接時,主要問題就變成了。我嘗試this解決方案,但當我做一個重定向(在控制器中,我只有1個返回視圖,其他方法做重定向)它創建一個新的對話,並找不到以前的一個。SessionAttributes打開新的瀏覽器標籤時

我還有一個關於這個triying使用春季會議的問題,這是here,但我不知道這是否也能起作用。

回答

5

你看過Spring的RedirectAttributes嗎?我自己並沒有使用它,但它聽起來像它應該做你想做的事情。 RedirectAttributes通常用於GET /重定向/ POST模式,並且at least one user似乎認爲以這種方式傳遞會話屬性是不好的做法,但是他們繼續提到似乎沒有更好的解決方案。總之,在文檔中所示的例子:

@RequestMapping(value = "/accounts", method = RequestMethod.POST) 
public String handle(Account account, BindingResult result, RedirectAttributes redirectAttrs) { 
    if (result.hasErrors()) { 
     return "accounts/new"; 
    } 
    // Save account ... 
    redirectAttrs.addAttribute("id", account.getId()).addFlashAttribute("message", "Account created!"); 
    return "redirect:/accounts/{id}"; 
} 

將添加「消息」屬性的RedirectModel,如果你的控制器重定向,那麼無論方法處理重定向可以訪問像這樣的數據:

@RequestMapping(value = "/accounts", method = RequestMethod.POST) 
public String handleRedirect(Model model) { 
    String message = (String) model.asMap().get("message"); 
    return new ModelAndView(); 
} 

因此添加會話屬性應該可以用同樣的方法。另有參考文獻here

編輯 我在瀏覽Spring文檔,他們也提到了這個註釋@SessionAttributes。從文檔:

類型級別@SessionAttributes註釋聲明特定處理程序使用的會話屬性。這通常會列出應該透明地存儲在會話或某些會話存儲中的模型屬性或模型屬性類型的名稱,作爲後續請求之間的表單支持bean。

這是你需要的嗎?

還有a link to documentation on flash attributes

+0

redirectAttributes的主要問題是我需要將所有變量放在單獨的屬性中,如果它們不是html的形式。 – Raider

2

這是我們拿出,無關與Spring的解決方案:

  1. 在您的應用程序的每個HTML表單,你將不得不包括一個隱藏字段。我們來命名這個字段CSRF_TOKEN。這個字段應該有一個隨機生成的值。該值被放置在會話和隱藏字段中。會話屬性的名稱爲SESSION_CSRF_TOKEN

  2. 將表單提交給服務器時,檢查會話中的值(SESSION_CSRF_TOKEN)是否等於HTTP請求參數CSRF_TOKEN中發送的值。如果不是,則顯示某種錯誤消息,並停止處理。如果他們是平等的,繼續。

如果用戶打開新選項卡或複製選項卡,服務器將重新呈現該頁面,並且將生成新的CSRF_TOKEN。因此,用戶將只能從新打開的選項卡提交表單,而不能從原始表單提交表單。

此解決方案提供額外的獎勵:它可以防止CSRF attacks

相關問題