sfr*_*frj 6 java jsf jpa download java-ee
我需要下载存储在数据库中的文件.我想我做了正确的查询并调用它我只是不知道如何将它连接到JSF页面中的按钮.另外我想知道,在将它传递到JSF页面之前,我是否必须将该图像保存在服务器的文件夹中.如果是这样,我该怎么做?
这是我用来从db返回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;
....
Run Code Online (Sandbox Code Playgroud)
这是一个简单的EJB,它调用该查询然后获取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;
}
Run Code Online (Sandbox Code Playgroud)
现在这是困扰我的部分,我在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...
}
}
Run Code Online (Sandbox Code Playgroud)
另外,我如何从commandButton中的JSF传递那个长id到managedBean?这是允许的吗?
<!-- How to pass the value of id from -->
<h:commandButton action="downloadController.startDownload(#{garbage.id})">
Run Code Online (Sandbox Code Playgroud)
Bal*_*usC 11
在EL中传递参数仅在web.xml
声明为Servlet 3.0并且servletcontainer也支持它时才有效(Glassfish 3,JBoss AS 6,Tomcat 7等).您的尝试中只有语法错误,这是正确的方法:
<h:commandButton action="#{downloadController.startDownload(garbage.id)}" />
Run Code Online (Sandbox Code Playgroud)
你甚至可以传递整个物体,在这种特殊情况下更好.
<h:commandButton action="#{downloadController.startDownload(garbage)}" />
Run Code Online (Sandbox Code Playgroud)
然后,该startDownload()
方法应设置响应头,以便webbrowser了解响应主体代表什么内容类型以及如何处理它,最后将内容写入响应主体.你可以借助这一切来做到这一切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();
}
Run Code Online (Sandbox Code Playgroud)
最后一行FacesContext#responseComplete()
是强制性的,以便JSF理解它不应导航到某个视图,因此可能会在之后使用另一个JSF页面使响应失真.
归档时间: |
|
查看次数: |
9311 次 |
最近记录: |