2011-03-31 41 views
5

我需要下載存儲在數據庫中的文件。我想我做了正確的查詢和調用它,我只是不知道如何將它連接到JSF頁面中的按鈕。 另外我想知道,我必須將該圖像保存在服務器的文件夾中,然後將其傳遞到JSF頁面。如果是這樣,我該怎麼做?如何使用JSF 2.0下載存儲在數據庫中的文件

這是查詢我使用從數據庫返回的byte []:

@NamedQuery(name = "downloadGarbage", query = "SELECT g.file FROM Garbage g WHERE g.id :idParam") 
@Entity 
public class Garbage implements Serializable { 
@Lob 
@Column(nullable = false) 
private byte[] file; 
.... 

這裏是調用,那麼該查詢得到的ID一個簡單的EJB:

@Stateless(name = "ejbs/FileDownloaderEJB") 
public class FileDownloaderEJB implements IFileDownloaderEJB { 

@PersistenceContext 
private EntityManager em; 

public byte[] downloadGarbage(Long id) { 
    Query query = em.createNamedQuery("downloadGarbage"); 
    query.setParameter("idParam", id); 

    Object o = query.getSingleResult(); 
    byte[] tmpArray = (byte[]) o; 
    return tmpArray; 
} 

現在這是混淆了我的部分,我怎麼可以與JSF頁面和託管bean上面?

@ManagedBean 
@RequestScoped 
public class DownloadController { 

@EJB 
private FileDownloaderEJB fileDownloaderEJB; 

    ... 

    private Garbage garbage; 

public void startDownload(Long id) { 
    fileDownloaderEJB.downloadGarbage(id); 
//HOW TO START THE DOWNLOAD? 
//Other Get Set Methods... 

} 

} 

此外,我怎麼能傳遞長期ID從JSF的managedBean從一個命令中?這是否允許?在EL

<!-- How to pass the value of id from --> 
<h:commandButton action="downloadController.startDownload(#{garbage.id})"> 

回答

10

傳遞參數僅當web.xml聲明爲3.0的Servlet和servletcontainer還支持它(Glassfish的3,JBoss應用服務器6,Tomcat的7等)的工作原理。這裏只有一個語法錯誤在你嘗試,這裏是正確的做法:

<h:commandButton action="#{downloadController.startDownload(garbage.id)}" /> 

你甚至可以沿着整個傳遞的對象,這是在這種特殊情況下更好。

<h:commandButton action="#{downloadController.startDownload(garbage)}" /> 

然後,使網頁瀏覽器瞭解什麼內容類型的響應體代表,並與它做什麼,最後寫的內容,以響應主體的startDownload()方法應該設置響應頭。你可以在ExternalContext的幫助下做到這一切。這裏有一個開球例如:

public void startDownload(Garbage garbage) { 
    FacesContext facesContext = FacesContext.getCurrentInstance(); 
    ExternalContext externalContext = facesContext.getExternalContext(); 
    externalContext.setResponseHeader("Content-Type", garbage.getContentType()); 
    externalContext.setResponseHeader("Content-Length", garbage.getContent().length); 
    externalContext.setResponseHeader("Content-Disposition", "attachment;filename=\"" + garbage.getFileName() + "\""); 
    externalContext.getResponseOutputStream().write(garbage.getContent()); 
    facesContext.responseComplete(); 
} 

FacesContext#responseComplete()的最後一行是強制性的,這樣JSF理解,它不應該導航到一些觀點,因此有可能事後malform與其他JSF頁面的響應。

+0

ContentType應該是什麼,如果它是.doc文件。該方法getContentType()應該返回「text/xml」還是「text/plain」? – sfrj 2011-03-31 13:37:20

+2

哦,一個Word文檔當然不是一個文本文件。對於'.doc',它是'application/msword',對於'.docx'則是'application/vnd.openxmlformats-officedocument.wordprocessingml.document'。如果要基於文件名以編程方式確定它,可以使用'ServletContext#getMimeType()'。另見http://stackoverflow.com/questions/2426773/when-do-browsers-send-application-octet-stream-as-content-type/2426952#2426952 – BalusC 2011-03-31 13:40:27

+0

謝謝,我會試試看 – sfrj 2011-03-31 14:05:40

相關問題