Fahim Parkar
Fahim Parkar

Reputation: 31637

file not downloading updated file

I am creating file using Java and generating link for download.

Let's say I create file myFile.xls and have link as below.

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

This will result as below.

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

Everytime I create new file, and click on above link, I always see the earlier file that I downloaded for the first time.

Is it happening because jsf cache the files?

Note : When I download file manually, I always see the updated file.

However using link, I always see the first file.

Any idea why this happening?

I think this is because of caching. If yes, how can I ignore this for this excel file only?

Upvotes: 1

Views: 65

Answers (1)

BalusC
BalusC

Reputation: 1108752

JSF isn't caching those resources at all. JSF is in the context of this question merely a HTTP traffic controller and HTML code generator. It's the webbrowser who's caching them. You can control this by setting the proper response headers as listed in this answer: How to control web page caching, across all browsers?.

The simplest way would be creating a servlet filter which is mapped on the URL pattern matching those downloads, e.g. /excel/* (your JSF source code and actual URL doesn't match each other, so it's somewhat guessing here), and set the headers in the doFilter() method:

@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);
    }

    // ...
}

Or, if you're serving those files via a servlet, then you could also just set those headers over there.

An alternative is to fool the webbrowser that it's a brand new resource by inlining a query string with a timestamp.

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

where #{now} is just an java.util.Date registered as request scoped bean in faces-config.xml (in case you're using JSF utility library OmniFaces; it has already one builtin). The webbrowser will treat any resource with a different query string as an unique and independent resource and therefore not reuse the cached version of the resource on the same URI (if the query string is different).

Upvotes: 1

Related Questions