2011-12-21 7 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はあなたの最初の問題は、あなたがAjaxリクエストでファイルをダウンロードしようとしているということです

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

今はテストする時間がありませんが、プライムフェイスAPI内のAJAXコールがダウンロード要求を「食べている」ということは間違いありません。あなたが見なければならないのは、actionlistenerを使用する代わりに、ダウンロードファイルのためにajax = "false" 'でを表示することです。これにより、更新をトリガーする代わりに持続するリンク(事前に動的に変更することができます)が作成されます。私はテーブルと同様の問題を抱えていましたが、これはすぐにそれをノックアウトしました。がんばろう。 –

+0

ありがとう! はajaxタグを置き換えますか?またはtreeNodeタグ(ドキュメントを表示するタグ)? – BRabbit27

答えて

2

です。これは不可能です。 AjaxはJavaScriptコードによって実行され、管理されます。 JavaScriptはセキュリティ制限のため名前を付けて保存ダイアログをトリガーする機能がありません。代わりに完全な同期要求を起動する必要があります。コンテンツの配置がattachmentに設定されている場合、元のページは同じままです。

したがって、少なくとも<h:commandButton>または<p:commandButton ajax="false">が必要です。あなたが<p:fileDownload>を使用しようとしたときにあなたが得た

あなたの第二の問題は、valueStreamedContent、ないvoidを返す方法を指している必要がありますということです。 voidメソッドにバインドしたため、何も返されません。

StreamedContent<p:fileDownload>という値に戻す必要があります。

第3の問題は、クラスパスリソースとしてファイルをServletContext#getResourceAsStream()で取得していることです(これはPrimeFacesのショーケースの例から盲目的にコピーしたものと信じていますが、それだけではかなり劣ります。 ServletContextをJSFのフードの下から取得する必要がありますが、これは元のコードと同じように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()方法と
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> 

String pathに変更引数で。

+0

Puf ...私はあなたのもの(同じ正確なコード)と私のいくつかのバリエーションを試しましたが、起こっている唯一のことはページをリフレッシュすることです(まるで別の場所にリダイレクトされるように)。 。 – BRabbit27

+0

私は前に 'でいくつかの奇妙な問題を見たことがあります。代わりに、通常の ''を試してください。 – BalusC

+0

Balusはここでお金で死んでいます:時々、コンポーネントの内部で動作が "不安定"です。メソッドを呼び出す代わりに、コレクションを持っていて、各要素は「ダウンロード可能な」ストリーミングされたコンテンツです。これは通常私が取るアプローチであり、動作します。 ajax = "false"を確認するためにダブルチェック - それはそれを壊すでしょう。 –

関連する問題