1

我正在使用 Java 创建文件并生成下载链接。

假设我创建文件 myFile.xls 并具有如下链接。

Please download data from <a href="#{msg['websiteWay']}ProjectUploadFiles/excel/#{MyLogin.loginname}_SurveyReport.xls">here</a>. 

这将导致如下。

Please download data from <a href="http://www.mywebsite.com/excel/admin_SurveyReport.xls">here</a>.

每次创建新文件并单击上面的链接时,我总是会看到我第一次下载的较早文件。

是因为 jsf 缓存文件而发生的吗?

注意:当我手动下载文件时,我总是看到更新的文件。

但是使用链接,我总是看到第一个文件。

知道为什么会这样吗?

我认为这是因为缓存。如果是,我怎么能只为这个excel文件忽略这个?

4

1 回答 1

1

JSF 根本不缓存这些资源。JSF 在这个问题的上下文中仅仅是一个 HTTP 流量控制器和 HTML 代码生成器。缓存它们的是网络浏览器。您可以通过设置此答案中列出的正确响应标头来控制这一点:How to control web page caching, across all browsers? .

最简单的方法是创建一个 servlet 过滤器,该过滤器映射到与这些下载匹配的 URL 模式,例如/excel/*(您的 JSF 源代码和实际 URL 不匹配,所以这里有点猜测),并在doFilter()方法中设置标题:

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

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        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);
    }

    // ...
}

或者,如果您通过 servlet 提供这些文件,那么您也可以在那里设置这些标头。

另一种方法是通过内联带有时间戳的查询字符串来欺骗网络浏览器,使其成为全新的资源。

Please download data from <a href="#{msg['websiteWay']}ProjectUploadFiles/excel/#{MyLogin.loginname}_SurveyReport.xls?#{now.time}">here</a>. 

where#{now}只是一个java.util.Date注册为请求范围的 bean faces-config.xml(如果您使用JSF 实用程序库 OmniFaces;它已经内置了一个)。网络浏览器会将具有不同查询字符串的任何资源视为唯一且独立的资源,因此不会在同一 URI 上重用资源的缓存版本(如果查询字符串不同)。

于 2013-09-30T16:31:36.880 回答