Eis o cenário: Uma aplicação JSF, onde numa determinada página seja necessário exibir documentos PDF. Estes ficam armazenados em banco de dados, num campo BLOB/CLOB de uma tabela. A pergunta: Como implemento isto?
Vamos lá, hora da diversão. Começamos criando uma Entity
para mapear a tabela que armazena o documento PDF:
DocumentoPdf.java:
@Entity public class DocumentoPdf implements Serializable { @Id private int id; //Este atributo corresponde ao campo BLOB/CLOB que armazena //o conteudo do documento PDF (Note a anotação @Lob) @Lob @Column private byte[] conteudo; //... Gets e Sets ... }
Agora, precisamos de uma forma de buscar os objetos desta Entity
no banco de dados. Vamos criar um DAO
, deixando o código de acesso ao banco fora do escopo do nosso exemplo:
Dao.java:
public class Dao { public DocumentoPdf buscarDocumento() { //Implemente aqui para retornar o objeto DocumentoPdf do Banco de Dados } }
Com o DAO
pronto, vamos para o principal: um método no ManagedBean
que pegue o array de bytes e envie para o navegador como um arquivo de documento PDF:
Control.java:
@ManagedBean public class Control implements Serializable { //Apenas para simplificar: carrega automaticamente a Entity através do DAO private DocumentoPdf documentoPdf = new Dao().buscarDocumento(); public void visualizarPdf() { FacesContext fc = FacesContext.getCurrentInstance(); // Obtem o HttpServletResponse, objeto responsável pela resposta do // servidor ao browser HttpServletResponse response = (HttpServletResponse) fc .getExternalContext().getResponse(); // Limpa o buffer do response response.reset(); // Seta o tipo de conteudo no cabecalho da resposta. No caso, indica que o // conteudo sera um documento pdf. response.setContentType("application/pdf"); // Seta o tamanho do conteudo no cabecalho da resposta. No caso, o tamanho // em bytes do pdf response.setContentLength(documentoPdf.getConteudo().length); // Seta o nome do arquivo e a disposição: "inline" abre no próprio navegador // Mude para "attachment" para indicar que deve ser feito um download response.setHeader("Content-disposition", "inline; filename=arquivo.pdf"); try { // Envia o conteudo do arquivo PDF para o response response.getOutputStream().write(documentoPdf.getConteudo()); // Descarrega o conteudo do stream, forçando a escrita de qualquer byte // ainda em buffer response.getOutputStream().flush(); // Fecha o stream, liberando seus recursos response.getOutputStream().close(); // Sinaliza ao JSF que a resposta HTTP para este pedido já foi gerada fc.responseComplete(); } catch (IOException e) { e.printStackTrace(); } } }
Por fim, vamos criar a página JSF para testar. O atributo target="_blank"
no h:commandLink
indica ao browser que o PDF deve ser aberto em uma nova aba. Retire este atributo caso queira exibir na aba atual:
index.xhtml:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"> <h:head /> <h:body> <h:form> <h:commandLink value="Visualizar PDF" action="#{control.visualizarPdf}" target="_blank" /> </h:form> </h:body> </html>
perfeito
ResponderExcluirfunciona no IE?
ResponderExcluirDeve funcionar sim, desde que no IE haja algum aplicativo configurado para ler PDF, como o Adobe Reader, por Exemplo.
ExcluirNas versões mais recentes do Firefox, já há um leitor PDF nativo, mesmo que não existem nenhum aplicativo leitor de PDF instalado.
Boa Tarde, estou com o seguinte problema, tenho meu arquivo pdf armazenado no banco de dados PostgreSQL. Fiz conforme exemplo acima, mas não estou conseguindo implementar para retornar o objeto DocumentoPdf do Banco de Dados na minha classe DAO. Poderia me ajudar?
ResponderExcluirOK, poste como está seu código no momento.
ExcluirFunciona direitinho! Valeu a dica.
ResponderExcluir