Как скачать файл, хранящийся в базе данных с помощью JSF 2.0 - PullRequest
6 голосов
/ 31 марта 2011

Мне нужно скачать файл, хранящийся в базе данных.Я думаю, что правильно сделал запрос и назвал его, я просто не знаю, как я могу подключить это к кнопке на странице JSF.Также мне интересно, нужно ли сохранять это изображение в папке на сервере, прежде чем передавать его на страницу JSF.Если так, как я могу это сделать?

Это запрос, который я использую для возврата байта [] из базы данных:

@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;
....

Вот простой 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 и управляемым бином?

@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...

}

}

Также как я могу передать этодлинный идентификатор управляемого элемента из JSF из команды commandButton?Это разрешено?

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

1 Ответ

11 голосов
/ 31 марта 2011

Передача параметров в EL работает только тогда, когда web.xml объявлен как Servlet 3.0, и сервлет-контейнер также поддерживает его (Glassfish 3, JBoss AS 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 понимает, что ему не следует переходить к какому-либо представлению, и, таким образом, потенциально может искажать ответ другого.Страница JSF впоследствии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...