2011-12-21 152 views
0

这是我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(); 
     } 
    } 
} 

但它不是下载文件,我用战斧树这种下载方法和它的工作,现在我想与PrimeFaces,但这不会下载该文件,并没有错误!

任何意见可能是错误的?

在此先感谢!

UPDATE

我有这样的修改,但不能让它下载文件。

 <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

我现在没有时间去测试它 - 但有可能是因为其在“吃”您的请求下载的primefaces API中的AJAX调用。你应该看看,而不是使用actionlistener显示下载文件的和'ajax =“false”'。这将创建一个链接(它可以提前动态更改),该链接将持续而不是触发更新。我在桌子上遇到了类似的问题,并且很快就将其解决了。祝你好运。 – 2011-12-22 01:37:53

+0

非常感谢! 替换了ajax标签?或者treeNode标签(显示文档的标签)? – BRabbit27 2011-12-22 05:21:10

回答

2

你的第一个问题是,你试图通过一个Ajax请求下载一个文件。这不可能。 Ajax由JavaScript代码执行和管理。 JavaScript已经由于安全限制而无法触发另存为对话。您需要改为启用一个完整的同步请求。如果内容配置设置为attachment,原始页面将保持不变。

所以,你至少需要一个<h:commandButton><p:commandButton ajax="false">

你,你当你试图使用<p:fileDownload>了第二个问题是,value必须指向返回StreamedContent,不void的方法。您已将其绑定到void方法,因此不会返回任何内容。

因此,您需要将的值返回StreamedContent

你的第三个问题是,你得到的ServletContext#getResourceAsStream()的文件作为类路径资源(我相信你盲目地从PrimeFaces copypasted展示例子,这又是本身也蛮可怜的,它可能只是使用了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

+0

Puf ...以及我尝试与你的(相同的确切代码)和我的一些变化,但唯一发生的是页面刷新(就像我将被重定向到其他地方),没有文件被下载.. – BRabbit27 2011-12-22 19:13:44

+0

我以前见过''的一些奇怪问题(我以前从来没有用过它,所以我不能详细介绍)。改为使用常规的''。 – BalusC 2011-12-22 19:21:09

+0

Balus在这里的钱已经死了:有时组件内部的行为“不稳定”。你可以尝试颠倒它,所以而不是一个方法调用你只是有一个集合和每个元素是一个“可下载的”流式内容 - 它通常是我采取的方法,它的工作原理。仔细检查以确保ajax =“false” - 它会破坏它。 – 2011-12-22 20:45:11