Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perform page navigation after a file download

I need to find a way to perform a page navigation after generating a file download. So far, I've got the file download ready and working:

FileInputStream stream = new FileInputStream(file);
        FacesContext fc = FacesContext.getCurrentInstance();
        ExternalContext ec = fc.getExternalContext();
        ec.responseReset();
        ec.setResponseContentType("application/octet-stream");
        ec.setResponseHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");

        OutputStream out = ec.getResponseOutputStream();

        byte[] outputByte = new byte[4096];

        while(stream.read(outputByte, 0, 4096) != -1)
        {
                out.write(outputByte, 0, 4096);
        }
        stream.close();
        out.flush();
        out.close();
        fc.responseComplete();

So far, I've try redirecting from the ExternalContext afterwards but i get an IllegalStateException.

ec.redirect(url)

I've also tried wrapping all the previous code in a string method that returns the page to be navigated at the end. That didn't work either.

Any recommendations?

like image 461
Roberto Betancourt Avatar asked Feb 16 '23 08:02

Roberto Betancourt


1 Answers

You can't return 2 responses to 1 request. You can return only 1 response to 1 request. A file download counts as one response and a redirect counts as another response.

Your best bet is to return a response which automatically initiates a new request in some way. The second response can then be returned to this automatically initiated request. JavaScript is very helpful in this with functions like window.location (to fire a new request in current window), window.open() (to fire a new request in a new window), and form.submit() (to submit a POST form).

The simplest way would be to redirect to the target page wherein some JavaScript is conditionally rendered (and immediately executed) which in turn triggers the file download by e.g. window.location or form.submit(). The window.open() is inappropriate if the download itself is already set as an attachment. Note that this approach doesn't redirect after the user has saved the file download, this is plain impossible as there's no client side event to hook on when the last bit of the download is saved. Instead, the redirect is first performed and then the file download.

If you've really a hard head in this, then you can always create an applet or webstart application which fully manages the saving of the downloaded file, so that you can easily perform a redirect after the last bit is saved. However, this is IMO plain clumsy (and even potentially bad for UX; for instance I personally hate this kind of "download managers" on several websites).

like image 149
BalusC Avatar answered Feb 24 '23 00:02

BalusC