2011-11-18 100 views
3

當我們使用:重定向副作用,使用瀏覽器的後退按鈕

  • JSF 1.2-1.2_07-B03-FCS
  • JSTL 1_1-MR2(特殊版本)
  • 的Java 1.6.0_22-B04
  • 的Eclipse 3.6.0(太陽神)
  • 的Tomcat 6.0.28(需要也運行EJB)
  • IE 7.0.5730.13
  • 杉木EFOX:6.0

我們有mainForm.jspfilterForm.jspexternalForm.jsp意見。

mainForm.jsp上有一個按鈕「過濾器」以轉換爲filterForm.jsp。它是由一個導航規則:

<h:commandButton value="Filter" action="#{mainBean.filterData}" /> 

mainBean.java代碼:

public String filterData() { 
    doStuff(); 
    return "filter"; 
} 

這最初過渡正確地filterForm.jsp。我們可以通過瀏覽器後退按鈕回到mainForm.jsp。我們可以反覆這樣做。

mainForm.jsp我們有一個表(實際上是一個ILog甘特圖,但我們認爲不重要),在圖表欄上有一個「彈出」菜單。其中一個菜單選項是重定向到externalForm.jsp

選擇 「重定向」 觸發mainBean.java下面的方法:

public void redirect(FacesMenuActionEvent event) { 
    if (svr == null) { 
     svr = new SetupURL(); // Simple code to set up the full URL 
    } 

    redirectUrl = svr.redirect(event); // URL of externalForm.jsp 
    svr.redirectData(redirectUrl); 
} 

這正常工作。該窗口轉換爲externalForm.jsp

如果我們按下externalForm.jsp上的瀏覽器後退按鈕,我們將轉回mainForm.jsp,事情看起來不錯。

如果我們再按下「過濾器」按鈕,代碼不執行filterData()方法,而是其執行redirect()方法,我們過渡到externalForm.jsp視圖,而不是filterForm.jsp視圖。

它爲什麼這樣做,我們如何強制呼叫filterData()而不是?

****************************************************************************** 

BalusC - thank you for your solution. With a few slight tweeks, it worked great. 

The changes I made to web.xml are: 

    <filter> 
     <filter-name>noCacheFilter</filter-name> 
     <filter-class>{my package name}.CacheControlFilter</filter-class> 
    </filter> 
    <filter-mapping> 
     <filter-name>noCacheFilter</filter-name> 
     <url-pattern>/faces/*</url-pattern> 
    </filter-mapping> 




Also, I found another solution: 

faces-config.xml add: 

    <lifecycle> 
     <phase-listener id="nocache">{my package name}. 
     CacheControlPhaseListener</phase-listener> 
    </lifecycle>  


Create file CacheControlPhaseListener.java: 

package {my package name}; 

import javax.faces.context.FacesContext; 
import javax.faces.event.PhaseEvent; 
import javax.faces.event.PhaseId; 
import javax.faces.event.PhaseListener; 
import javax.servlet.http.HttpServletResponse; 

public class CacheControlPhaseListener implements PhaseListener { 

    public PhaseId getPhaseId() { 
     return PhaseId.RENDER_RESPONSE; 
    } 

    public void afterPhase(PhaseEvent event) { 
    } 

    public void beforePhase(PhaseEvent event) { 
     FacesContext facesContext = event.getFacesContext(); 
     HttpServletResponse response = (HttpServletResponse) facesContext 
       .getExternalContext().getResponse(); 
     response.addHeader("Pragma", "no-cache"); 
     response.addHeader("Cache-Control", "no-cache"); 
     // Stronger according to blog comment below that references HTTP spec 
     response.addHeader("Cache-Control", "no-store"); 
     response.addHeader("Cache-Control", "must-revalidate"); 
     // some date in the past 
     response.addHeader("Expires", "Mon, 8 Aug 2006 10:00:00 GMT"); 
    } 
} 

Both seem to work. 



Thanks, 
John 

回答

9

瀏覽器後退按鈕從瀏覽器緩存中請求結果頁面。它不會從服務器請求一個全新的頁面。在你的特定情況下,很可能緩存頁面包含當前無效的JSF視圖狀態。

最佳解決方法是指示瀏覽器不緩存動態JSF頁面,而是每次直接從服務器請求它。在web.xml

@Override 
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException { 
    HttpServletResponse res = (HttpServletResponse) response; 
    res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1. 
    res.setHeader("Pragma", "no-cache"); // HTTP 1.0. 
    res.setDateHeader("Expires", 0); // Proxies. 
    chain.doFilter(request, response); 
} 

地圖這對FacesServlet相同<servlet-name>:你可以這樣做與Filter其在doFilter()方法如下行的幫助。例如。

<filter> 
    <filter-name>noCacheFilter</filter-name> 
    <filter-class>com.example.NoCacheFilter</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>noCacheFilter</filter-name> 
    <servlet-name>facesServlet</servlet-name> 
</filter-mapping> 
+0

謝謝 - 請參閱上面的其他編輯。 –

+0

也可以,使用與'FacesServlet'相同的URL模式。如果servlet名稱映射不適合你,那麼你顯然只是指定了錯誤的servlet名稱。有時它只是' Faces Servlet'。只要看看你的'web.xml'。 'PhaseListener'對於這個特殊的目的來說太笨拙了,千萬不要想這個。您對操作JSF生命週期或組件樹不感興趣。你只對修改HTTP響應感興趣。爲此,「過濾器」是最好的套裝。 – BalusC

+0

是的,我現在看到。無論如何,我仍然使用您的解決方案,但是感謝您解釋PhaseListener解決方案出了什麼問題。 –

相關問題