下载文件后执行页面导航

时间:2013-06-05 01:57:11

标签: jsf navigation download

我需要找到一种在生成文件下载后执行页面导航的方法。到目前为止,我已准备好文件下载并正常工作:

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();

到目前为止,我尝试从ExternalContext重定向,但是我得到了IllegalStateException。

ec.redirect(url)

我还尝试将所有以前的代码包装在一个字符串方法中,该方法返回最后要导航的页面。这也不起作用。

有什么建议吗?

2 个答案:

答案 0 :(得分:6)

您不能向1个请求返回2个回复。您只能对1个请求返回1个响应。文件下载计为一个响应,重定向计为另一个响应。

最好的办法是返回一个以某种方式自动发起新请求的响应。然后可以将第二个响应返回到此自动启动的请求。 JavaScript在window.location(在当前窗口中触发新请求),window.open()(在新窗口中触发新请求)和form.submit()等函数中非常有用。提交POST表格。)

最简单的方法是重定向到目标页面,其中某些JavaScript被有条件地呈现(并立即执行),这反过来又触发文件下载。 window.locationform.submit()。如果下载本身已设置为附件,则window.open()不合适。请注意,在用户保存文件下载后,此方法不会重定向,这是不可能的,因为在保存下载的最后一位时没有客户端事件可以挂钩。相反,首先执行重定向,然后执行文件下载。

如果你真的很难,那么你总是可以创建一个applet或webstart应用程序来完全管理下载文件的保存,这样你就可以在保存最后一位后轻松执行重定向。然而,这是IMO简单笨拙(甚至可能对用户体验有害;例如我个人讨厌在几个网站上使用这种“下载管理器”)。

答案 1 :(得分:1)

感谢@BalusC我做到了!从第一页我只是执行导航,在登录页面上我包含以下代码:

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