當我們使用:重定向副作用,使用瀏覽器的後退按鈕
- 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.jsp
,filterForm.jsp
和externalForm.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
謝謝 - 請參閱上面的其他編輯。 –
也可以,使用與'FacesServlet'相同的URL模式。如果servlet名稱映射不適合你,那麼你顯然只是指定了錯誤的servlet名稱。有時它只是' Faces Servlet servlet-name>'。只要看看你的'web.xml'。 'PhaseListener'對於這個特殊的目的來說太笨拙了,千萬不要想這個。您對操作JSF生命週期或組件樹不感興趣。你只對修改HTTP響應感興趣。爲此,「過濾器」是最好的套裝。 –
BalusC
是的,我現在看到。無論如何,我仍然使用您的解決方案,但是感謝您解釋PhaseListener解決方案出了什麼問題。 –