文件未下载更新的文件

时间:2013-09-30 15:23:42

标签: html jsf-2 hyperlink

我正在使用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文件?

1 个答案:

答案 0 :(得分:1)

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

最简单的方法是创建一个servlet过滤器,该过滤器映射到匹配这些下载的URL模式,例如: /excel/*(您的JSF源代码和实际网址彼此不匹配,所以这里有点猜测),并在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提供这些文件,那么您也可以在那里设置这些标题。

另一种方法是通过内联带有时间戳的查询字符串来欺骗webbrowser它是一个全新的资源。

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

其中#{now}只是java.util.Datefaces-config.xml中注册为请求范围的bean(如果您使用JSF utility library OmniFaces;它已经有一个内置)。 webbrowser会将具有不同查询字符串的任何资源视为唯一且独立的资源,因此不会在同一URI上重用资源的缓存版本(如果查询字符串不同)。