Jsf 从primefaces树下载文件
这是我的Jsf 从primefaces树下载文件,jsf,tree,download,primefaces,Jsf,Tree,Download,Primefaces,这是我的xhtml代码 <p:tree value="#{documentsController.root}" var="node" selectionMode="single" dynamic="true"> <p:treeNode expandedIcon="ui-icon-folder-open" co
xhtml代码
<p:tree value="#{documentsController.root}"
var="node" selectionMode="single"
dynamic="true">
<p:treeNode
expandedIcon="ui-icon-folder-open"
collapsedIcon="ui-icon-folder-collapsed">
<h:outputText value="#{node}" />
</p:treeNode>
<p:treeNode type="file" icon="ui-icon-document">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:ajax event="select" listener="#{documentsController.onNodeSelect}"/>
</p:tree>
但它并没有下载文件,我用这个下载方法下载了战斧树,它成功了,现在我尝试使用PrimeFaces,但它没有下载文件,没有错误
有什么不对劲的地方吗
提前谢谢
更新
我有这个修改,但不能让它下载文件
<p:tree value="#{documentsController.root}"
var="node" selectionMode="single"
dynamic="true">
<p:treeNode
expandedIcon="ui-icon-folder-open"
collapsedIcon="ui-icon-folder-collapsed">
<h:outputText value="#{node}" />
</p:treeNode>
<p:treeNode type="file" icon="ui-icon-document">
<p:commandButton value="#{node}" ajax="false">
<p:fileDownload value="#{documentsController.download(node)}" />
</p:commandButton>
</p:treeNode>
</p:tree>
第一个问题是您试图通过Ajax请求下载文件。这是不可能的。Ajax由JavaScript代码执行和管理。由于安全限制,JavaScript没有触发另存为对话的工具。您需要触发一个完全同步请求。如果内容配置设置为
附件
,则原始页面将保持不变
因此,您至少需要一个
或
您在尝试使用
时遇到的第二个问题是值必须指向返回StreamedContent
的方法,而不是void
。您已将其绑定到void
方法,因此不会返回任何内容
因此,您需要在
值上返回StreamedContent
第三个问题是,您通过ServletContext#getResourceAsStream()
将文件作为类路径资源获取(我相信您是盲目地从PrimeFaces showcase示例中复制粘贴的,而PrimeFaces showcase示例本身也非常糟糕,它可能只是使用了ExternalContext#getResourceAsStream()
而不需要从JSF的引擎盖下抓取ServletContext
,但除此之外),而不是像原始代码那样抓取FileInputStream
因此,任何一种解决方案都必须有助于:
<p:treeNode type="file" icon="ui-icon-document">
<p:commandButton value="#{node}" ajax="false">
<p:fileDownload value="#{documentsController.download(node)}" />
</p:commandButton>
</p:treeNode>
或
使用原始的onNodeSelect()
方法,参数更改为String path
,我现在没有时间测试它——但很可能是primefaces API中的AJAX调用“吃掉”了您的下载请求。您应该注意的是,不要对下载文件使用带有“ajax=”false“的actionlistener显示。这将创建一个链接(可以提前动态更改),该链接将保持不变,而不是触发更新。我的桌子也有类似的问题,这很快就把它弄倒了。祝你好运,非常感谢!替换ajax标记?或者treeNode标签(显示文档的标签)?Puf。。。我试过使用你的(相同的代码)和我的一些变体,但唯一发生的事情是页面刷新(好像我将被重定向到其他地方)并且没有下载任何文件…我以前看到过
的一些奇怪问题(我自己以前从未使用过,所以我无法详细说明)。试试常规的
吧。巴卢斯在这里非常有钱:有时组件内部的行为“不稳定”。您可以尝试将其反转,这样您就不需要方法调用,而只需拥有一个集合,每个元素都是“可下载”的流式内容——这通常是我采用的方法,并且可以正常工作。仔细检查以确保ajax=“false”--它将破坏它。
public void download(String path) {
File f = new File(path);
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
InputStream is = ((ServletContext)externalContext.getContext()).getResourceAsStream(path);
file = new DefaultStreamedContent(is, externalContext.getMimeType(f.getName()), f.getName());
}
public StreamedContent getFile(){
return file;
}
<p:treeNode type="file" icon="ui-icon-document">
<p:commandButton value="#{node}" ajax="false">
<p:fileDownload value="#{documentsController.download(node)}" />
</p:commandButton>
</p:treeNode>
public StreamedContent download(String path) {
File file = new File(path);
InputStream input = new FileInputStream(file);
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
return new DefaultStreamedContent(input, externalContext.getMimeType(file.getName()), file.getName());
}
<p:treeNode type="file" icon="ui-icon-document">
<h:commandButton value="#{node}" action="#{documentsController.download(node)}" />
</p:treeNode>