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