I need to download a file stored in a database. I think i did correctly the query and called it i just dont know how can i connect that to a button in a JSF page. Also i am wondering, do i have to save that image in a folder at the server before passing it to the JSF page. If so, How can i do that?
This is the query i use to return the byte[] from the db:
@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;
....
Here is a simple EJB that calls that query then get the id:
@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;
}
Now this is the part that confuses me, how can i that above with the JSF page and managed 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...
}
}
Also how can i pass that long id to the managedBean from the JSF from within a commandButton? Is this allowed?
<!-- How to pass the value of id from -->
<h:commandButton action="downloadController.startDownload(#{garbage.id})">
Passing parameters in EL only works when the
web.xml
is declared as Servlet 3.0 and the servletcontainer also supports it (Glassfish 3, JBoss AS 6, Tomcat 7, etc). There's only a syntax error in your attempt, here's the correct way:You can even pass whole objects along, that's better in this particular case.
Then, the
startDownload()
method should set the response headers so that the webbrowser understands what content type the response body represents and what to do with it and finally write the content to the response body. You can do it all with help ofExternalContext
. Here's a kickoff example:The last line with
FacesContext#responseComplete()
is mandatory so that JSF understands that it shouldn't navigate to some view and thus potentially malform the response with another JSF page afterwards.