我正在使用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文件?
答案 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.Date
在faces-config.xml
中注册为请求范围的bean(如果您使用JSF utility library OmniFaces;它已经有一个内置)。 webbrowser会将具有不同查询字符串的任何资源视为唯一且独立的资源,因此不会在同一URI上重用资源的缓存版本(如果查询字符串不同)。