这是我的xhtml-code
<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>
这是支持bean
@ManagedBean
@ViewScoped
public class DocumentsController implements Serializable {
TreeNode root;
//TreeNode[] selectedNodes;
@PostConstruct
public void init() {
root = new DefaultTreeNode("SRC", null);
TreeNode node0 = new DefaultTreeNode("A", root);
TreeNode node1 = new DefaultTreeNode("B", root);
TreeNode node2 = new DefaultTreeNode("C", root);
TreeNode node3 = new DefaultTreeNode("file", "D", node0);
TreeNode node4 = new DefaultTreeNode("file", "E", node0);
TreeNode node5 = new DefaultTreeNode("file", "F", node0);
String p = "C:\\Users\\federico.martinez\\Desktop\\a.wmv";
TreeNode node6 = new DefaultTreeNode("file", new File(p), node1);
TreeNode node7 = new DefaultTreeNode("file", "h", node1);
TreeNode node8 = new DefaultTreeNode("file", "i", node1);
}
public TreeNode getRoot() {
return root;
}
/*
public void setSelectedNodes(TreeNode[] selectedNodes){
this.selectedNodes = selectedNodes;
}
public TreeNode[] getSelectedNodes(){
return selectedNodes;
}*/
public void onNodeSelect(NodeSelectEvent event) {
if (event.getTreeNode().getType().equals("file")) {
File file = new File(event.getTreeNode().getData().toString());
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
externalContext.setResponseHeader("Content-Type", externalContext.getMimeType(file.getName()));
externalContext.setResponseHeader("Content-Length", String.valueOf(file.length()));
externalContext.setResponseHeader("Content-Disposition", "attachment;filename=\"" + file.getName() + "\"");
InputStream input = null;
OutputStream output = null;
try {
input = new FileInputStream(file);
output = externalContext.getResponseOutputStream();
IOUtils.copy(input, output);
} catch (FileNotFoundException ex) {
System.out.println("FileNotFound: " + ex.getMessage());
} catch (IOException ex) {
System.out.println("IO: " + ex.getMessage());
} finally {
IOUtils.closeQuietly(output);
IOUtils.closeQuietly(input);
}
facesContext.responseComplete();
}
}
}
但是它没有下载文件,我在Tomahawk树上使用了这个下载方法并且它有效,现在我正在尝试使用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>
和backbean是
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;
}
答案 0 :(得分:2)
您的第一个问题是您尝试通过Ajax请求下载文件。这是不可能的。 Ajax由JavaScript代码执行和管理。 JavaScript由于安全限制而无法触发另存为对话。您需要启动一个完整的同步请求。如果内容处置设置为attachment
,原始页面将保持不变。
因此,您至少需要<h:commandButton>
或<p:commandButton ajax="false">
。
您尝试使用<p:fileDownload>
时遇到的第二个问题是value
必须指向返回StreamedContent
而不是void
的方法。你已将它绑定到void
方法,因此不会返回任何内容。
因此,您需要在StreamedContent
值上返回<p:fileDownload>
。
你的第三个问题是你正在通过ServletContext#getResourceAsStream()
将文件作为类路径资源获取(我相信你会盲目地从PrimeFaces展示的例子中进行复制,而这本身也很差,它可能只是用过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>
与
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>
使用原始onNodeSelect()
方法,参数更改为String path
。