5

我有一个将数据发布到外部页面的 JSF 页面。数据是从一个 JSF 托管 bean 加载的,该 bean 在发布数据中生成一个唯一 ID。

我有一个问题,用户单击结帐按钮然后导航回同一页面并再次按下结帐按钮。帖子数据没有更新。此外,根本不调用 bean。无论如何强制JSF重新加载页面和表单数据?

<form action="#{checkoutBean.externalUrl}" method="post"
    id="payForm" name="payForm">
       <input type="hidden" value="#{checkoutBean.uniqueID}" />
       <input type="submit" value="Proceed to Checkout" />
</form>
4

2 回答 2

10

该页面可能是从浏览器缓存中加载的。这本质上是无害的,但确实让最终用户感到困惑,因为他/她错误地认为它确实来自服务器。您可以通过查看浏览器的 Web 开发人员工具集中的 HTTP 流量监视器轻松确认这一点(在 Chrome/FireFox23+/IE9+ 中按 F12 并检查“网络”部分)。

您基本上需要告诉浏览器不要缓存(动态)JSF 页面。这样,浏览器将实际向服务器请求页面(并由此触发托管 bean 的正确创建/初始化等),而不是从其缓存中显示先前请求的页面。

通常,这是通过一个简单的servlet 过滤器来完成的,如下所示:

@WebFilter("/app/*")
public class NoCacheFilter implements Filter {

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

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

        chain.doFilter(req, res);
    }

    // ...
}

/app/*您要关闭浏览器缓存的示例 URL 模式在哪里。如有必要,您可以将其映射到/**.xhtml甚至映射到servletNames={"Faces Servlet"}.

如果您碰巧使用 JSF 实用程序库OmniFaces,那么您可以CacheControlFilter通过添加以下条目来使用它的内置web.xml(它演示了对 的直接映射FacesServlet,这意味着每个动态 JSF 页面都不会被缓存):

<filter>
    <filter-name>noCache</filter-name>
    <filter-class>org.omnifaces.filter.CacheControlFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>noCache</filter-name>
    <servlet-name>facesServlet</servlet-name>
</filter-mapping>

另请参阅陈列柜

于 2012-12-31T14:26:33.980 回答
5

我找到了一个适用于 JSF 的解决方案,而无需创建 servlet-filter。只需将下面的行放到您的 .xhtml 页面中。

<f:event type="preRenderView" listener="#{facesContext.externalContext.response.setHeader('Cache-Control', 'no-cache, no-store')}" />
于 2016-04-07T11:45:40.307 回答