2014-12-29 144 views
0

我有一個任務,顯示從數據庫中提取的PDF作爲彈出在我的JSF應用程序中點擊鏈接。但是,我的模式面板不會渲染PDF。相反,我在面板的左上角看到一個黑灰色的小方框。a4j:mediaOutput not rendering PDF

這裏是我的XHTML代碼:

<rich:column styleClass="viewUserTable"> 
<f:facet name="header"> 
    <h:outputText value="Pdf" /> 
</f:facet> 
<h:outputLink value="#" id="link" style="color:blue;margin: 0 auto;"> 
    Proof 
    <rich:componentControl for="panel" attachTo="link" 
     operation="show" event="onclick" /> 
</h:outputLink> 
<rich:modalPanel id="panel" width="350" height="100"> 
    <f:facet name="header"> 
     <h:outputText value="PDF"></h:outputText> 
    </f:facet> 
    <a4j:mediaOutput element="object" mimeType="application/pdf" 
     id="media" session="false" createContent="#{getMyBean.showPdf}" 
     value="1" style="width:800px; height:600px;" cacheable="false" 
     standby="loading..."> 
    </a4j:mediaOutput> 
</rich:modalPanel> 

這裏是我打電話給我的豆爲<a4j:mediaOutput>創建內容的方法。

public void showPdf(OutputStream stream, Object object) throws SQLException, IOException { 

    Blob proof= myObject.getPdf(someValue);//DB call to get the pdf 
    InputStream inStream = proof.getBinaryStream(); 
    int length = -1; 
    byte[] buffer = new byte[4096]; 

    while ((length = inStream.read(buffer)) != -1) { 
     stream.write(buffer, 0, length); 
    } 
} 

我不知道在<a4j:mediaOutput>value屬性的重要性,但我發現一個例子互聯網上有類似的內容是被取出從DB和和值設爲1時我米使用RichFaces的3.3 。

回答

0

我的一個朋友今天向我提出了這個問題,並且像你一樣,我一直在努力想出一個解決方案。經過一段時間學習servlet我可以解決這個問題。

你的方法應該是這樣的:

public void showPdf(OutputStream stream, Object object) throws SQLException, IOException { 

    Blob proof = myObject.getPdf(someValue);//DB call to get the pdf 

    FacesContext context = FacesContext.getCurrentInstance(); 
    HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse(); 
    ServletOutputStream sout = null; 

    response.setContentType("application/pdf"); 
    //set a constant for a name to avoid cache and duplicate files on server 
    response.setHeader("Content-Disposition","filename=fileName_" + (new Date()).getTime() + ".pdf"); 

    response.setHeader("Content-Transfer-Encoding", "binary;"); 
    response.setHeader("Pragma", " "); 
    response.setHeader("Cache-Control", " "); 
    response.setHeader("Pragma", "no-cache;"); 
    response.setDateHeader("Expires", new java.util.Date().getTime()); 
    //Here you will have to pass to total lengh of bytes 
    //as I used a file I called length method 
    response.setContentLength(Long.valueOf( proof.someByteLengthProperty() ).intValue()); 

    sout = response.getOutputStream(); 
    byte[] buf = new byte[4096]; 
    InputStream is = new FileInputStream(proof.getBinaryStream()); 
    int c = 0; 
    while ((c = is.read(buf, 0, buf.length)) > 0) { 
     sout.write(buf, 0, c); 
    } 
    sout.flush(); 
    is.close(); 

} 

似乎只有寫出OutputStream是不夠的,所以你必須創建一個ServletOutputStream併發送throghout的「FacesContext的」,因此它可以使輸出如果它正在發送下載流。