2011-10-20 63 views
6

我有一個關於面部導航的問題。faces-redirect和後退按鈕導致其他鏈接不正常工作

所以我有一個頁面需要一個請求參數來加載一個特定的用戶。該頁面顯示一個commandLink列表,單擊該列表時,將使用隱式導航重定向到另一個頁面。用戶通過調用「preRenderView」中的方法加載。

我們重定向到的頁面也需要一個請求參數來確定要加載哪個案例。該頁面也使用preRenderView。

這兩個頁面都有視圖作用域的bean。

這對於按下的FIRST鏈接來說非常棒。第一頁重定向到新的URL,並按預期加載案例。但是,如果我點擊瀏覽器的後退按鈕,然後點擊另一個鏈接,該頁面不會重定向。它更新(取而代之),顯然,不會購買案件。

刷新後,我可以點擊一個鏈接,它會正確重定向。

現在,所有這些工作完全正常,當第一頁的bean被保留在會話中,但我不想濫用會話狀態,並且我認爲它不應該被要求保存這些數據會議。

我知道我可以通過具有網頁自動刷新,當我點擊後退按鈕(因爲該視圖將被重新創建),但我不知道這是正確的解決辦法解決這個問題。 (也不知道我會如何強制這個)

有沒有人有任何建議?這似乎是一個相當常見的用例,但我無法找到任何示例。

謝謝!

回答

11

基本上,你需要告訴瀏覽器,同時具有節能方法設置爲(默認)server視圖狀態不緩存動態生成的JSF頁面。視圖狀態由生成的JSF頁面形式的<input type="hidden" name="javax.faces.ViewState">字段以視圖狀態標識符作爲輸入值進行跟蹤。當你提交一個頁面並導航到一個不同的頁面時,視圖狀態在服務器端被丟棄,並且不再存在。從瀏覽器緩存中取回頁面仍會爲您提供舊的視圖狀態標識符作爲隱藏輸入的值。提交該表單根本不起作用,因爲服務器端沒有查看狀態。

你想直接從服務器,而不是從瀏覽器緩存中取得一個新的新的一頁。爲了告訴瀏覽器要做到這一點,創建一個Filter這樣的:

@WebFilter(servletNames={"Faces Servlet"}) 
public class NoCacheFilter implements Filter { 

    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 
     HttpServletRequest httpReq = (HttpServletRequest) request; 
     HttpServletResponse httpRes = (HttpServletResponse) response; 

     if (!httpReq.getRequestURI().startsWith(httpReq.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER)) { // Skip JSF resources (CSS/JS/Images/etc) 
      httpRes.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1. 
      httpRes.setHeader("Pragma", "no-cache"); // HTTP 1.0. 
      httpRes.setDateHeader("Expires", 0); // Proxies. 
     } 

     chain.doFilter(request, response); 
    } 

    // ... 
} 

這樣的後退按鈕就會發出fullworthy HTTP請求,這應該重新創建視圖狀態,並與形式導致頁面正確的視圖狀態隱藏字段值。

+5

Balus,你是神。謝謝。 – jjross

相關問題