Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/jsf/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何流式下载文件并显示JSF faces消息?_Jsf_Jsf 2_Download_Message - Fatal编程技术网

如何流式下载文件并显示JSF faces消息?

如何流式下载文件并显示JSF faces消息?,jsf,jsf-2,download,message,Jsf,Jsf 2,Download,Message,我们将按照SO问题中详述的过程,将二进制文件流式传输给用户 通常,工作流按预期工作,但在生成导出文件的过程中,可能会发生可恢复的错误,我们希望将这些错误显示为对用户的警告。在这种情况下,仍应生成文件本身。因此,我们希望导出继续并显示faces消息 只是强调一下:是的,数据有点不正常,但我们的用户希望导出继续并接收有缺陷的文件。然后,他们希望查看该文件,联系他们的供应商,并向其发送有关该漏洞的消息 所以我需要在任何情况下完成导出 但这并不是我们想要的结果。我创建了一个简化的示例来说明我们的方法 作

我们将按照SO问题中详述的过程,将二进制文件流式传输给用户

通常,工作流按预期工作,但在生成导出文件的过程中,可能会发生可恢复的错误,我们希望将这些错误显示为对用户的警告。在这种情况下,仍应生成文件本身。因此,我们希望导出继续并显示faces消息

只是强调一下:是的,数据有点不正常,但我们的用户希望导出继续并接收有缺陷的文件。然后,他们希望查看该文件,联系他们的供应商,并向其发送有关该漏洞的消息

所以我需要在任何情况下完成导出

但这并不是我们想要的结果。我创建了一个简化的示例来说明我们的方法

作为替代方案,我们正在考虑一个Bean,它将保存消息并在导出后显示它们。但也许有一种方法可以通过JSF内置机制实现这一点

控制器

import java.io.ByteArrayInputStream;
导入java.io.IOException;
导入java.io.OutputStream;
导入javax.faces.application.FacesMessage;
导入javax.faces.bean.ManagedBean;
导入javax.faces.bean.RequestScope;
导入javax.faces.context.ExternalContext;
导入javax.faces.context.FacesContext;
导入org.apache.tomcat.util.http.fileupload.util.Streams;
@ManagedBean
@请求范围
公共类导出控制器{
公共空间导出(){
FacesContext fc=FacesContext.getCurrentInstance();
ExternalContext ec=fc.getExternalContext();
byte[]exportContent=“Hy Buddys,谢谢您的帮助!”.getBytes();
//这里发生了一些用户应该知道的不好的事情
//但此消息不会发送给用户
fc.addMessage(空,新面孔消息(“记录2有缺陷”);
ec.responseReset();
ec.setResponseContentType(“文本/普通”);
ec.setResponseContentLength(exportContent.length);
String attachmentName=“附件;文件名=\”导出.txt\”;
ec.setResponseHeader(“内容处置”,附件名称);
试一试{
OutputStream output=ec.getResponseOutputStream();
复制(新的ByteArrayInputStream(exportContent),输出,false);
}捕获(IOEX异常){
例如printStackTrace();
}
fc.responseComplete();
}
}
JSF页面


因为您实际上是在执行文件下载响应,而不是JSF响应,所以在相同的请求发生时不可能添加消息。对于我来说,避免黑客异步请求的最干净的解决方案是使用
@ViewScoped
bean,分两步完成任务。因此,要有一个按钮来准备您的文件,稍后通知用户并允许用户在文件准备好后下载:

@ManagedBean
@视域
公共类ExportController实现可序列化{
私有字节[]导出内容;
公共布尔值isReady(){
返回exportContent!=null;
}
公共空间导出(){
FacesContext fc=FacesContext.getCurrentInstance();
ExternalContext ec=fc.getExternalContext();
ec.responseReset();
ec.setResponseContentType(“文本/普通”);
ec.setResponseContentLength(exportContent.length);
String attachmentName=“附件;文件名=\”导出.txt\”;
ec.setResponseHeader(“内容处置”,附件名称);
试一试{
OutputStream output=ec.getResponseOutputStream();
复制(新的ByteArrayInputStream(exportContent),输出,false);
}捕获(IOEX异常){
例如printStackTrace();
}
fc.responseComplete();
}
公共无效准备文件(){
exportContent=“Hy Buddys,谢谢您的帮助!”.getBytes();
//这里发生了一些用户应该知道的不好的事情
FacesContext.getCurrentInstance().addMessage(空,
新面孔信息(“记录2有缺陷”);
}
}

注意:此解决方案可能适用于小文件(其全部内容存储在内存中,而用户保持在同一视图中)。但是,如果您要将其用于大文件(或大量用户),最好将其内容存储在临时文件中,并显示指向该文件的链接,而不是下载按钮。这就是@BalusC在下面的参考中所建议的

另请参见:

您可以尝试以下方法:
对于primefaces,您可以使用远程命令而不是命令链接,并使用其名称onsuccess调用它。否则,为commandlink提供一个小部件变量并调用它的click方法。

+1以获得正确的SSCCE示例。
org.apache.tomcat.util.http.fileupload.util.Streams
是特定于tomcat的。您可以使用JS调用下一个操作。@BalusC很高兴看到您的JS解决方案。你能发布一个链接吗?添加更多的描述和有用的内容来支持你的答案会很有帮助。否则这将被删除。