Perform page navigation after a file download

爱⌒轻易说出口 提交于 2020-04-05 15:29:06

问题


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?


回答1:


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).




回答2:


Thanks to @BalusC I did it! From the first page i just perform the navigation and on the landing page i included the following code:

           <c:if test="#{bean.readyForDownload}">
                <script>
                window.onload = function() {
                    document.getElementById('form:link').onclick();
                }
                </script>


            <h:form id="form">
                <h:commandLink id="link" action="#{bean.prepareFileDownload()}"/>
            </h:form>
           </c:if>


来源:https://stackoverflow.com/questions/16930352/perform-page-navigation-after-a-file-download

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!