Olá, tenho uma página jsf onde carrego os dados de uma entidade, entre os dados existe um arquivo anexado(pdf, xls, jpg etc.).
Gostaria de que, ao clicar no nome do arquivo, fizesse o download do arquivo.
Se alguém puder ajudar de alguma forma obrigado.
Método que uso para adicionar o arquivo :
public void doUpload(FileUploadEvent fileUploadEvent) throws IOException {
UploadedFile uploadedFile = fileUploadEvent.getFile();
String fileNameUploaded = uploadedFile.getFileName();
long fileSizeUploaded = uploadedFile.getSize();
// System.out.println(uploadedFile);
String infoAboutFile = "<br/> Arquivo recebido: <b>" + fileNameUploaded + "</b><br/>"
+ "Tamanho do Arquivo: <b>" + fileSizeUploaded + "</b>";
FacesContext facesContext = FacesContext.getCurrentInstance();
facesContext.addMessage(null, new FacesMessage("Sucesso", infoAboutFile));
arquivo = (IOUtils.toByteArray(uploadedFile.getInputstream()));
entradaAcidente.setAttach(arquivo);
nomeArquivo = uploadedFile.getFileName();
}
Entidade:
@Entity
@Table(name = "entrada_acidente")
public class EntradaAcidente implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private Date dataCriacao;
private String observacao;
private BigDecimal valorDesconto = BigDecimal.ZERO;
private BigDecimal valorTotal = BigDecimal.ZERO;
private StatusEntradaAcidente status = StatusEntradaAcidente.ORCAMENTO;
private FormaPagamento formaPagamento;
private Usuario vendedor;
private Cliente cliente;
private Ocorrencia ocorrencia1;
private List<ItemDespesa> itens = new ArrayList<>();
@Lob
@Column(columnDefinition = "LONGBLOB")
private byte[] comprovante;
private String fileName;
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
@Id
@GeneratedValue
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Lob
public byte[] getComprovante() {
return comprovante;
}
public void setComprovante(byte[] comprovante) {
this.comprovante = comprovante;
}
@NotNull
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "data_criacao", nullable = false)
public Date getDataCriacao() {
return dataCriacao;
}
public void setDataCriacao(Date dataCriacao) {
this.dataCriacao = dataCriacao;
}
@Column(columnDefinition = "text")
public String getObservacao() {
return observacao;
}
public void setObservacao(String observacao) {
this.observacao = observacao;
}
@NotNull
@Column(name = "valor_desconto", nullable = false, precision = 10, scale = 2)
public BigDecimal getValorDesconto() {
return valorDesconto;
}
public void setValorDesconto(BigDecimal valorDesconto) {
this.valorDesconto = valorDesconto;
}
@NotNull
@Column(name = "valor_total", nullable = false, precision = 10, scale = 2)
public BigDecimal getValorTotal() {
return valorTotal;
}
public void setValorTotal(BigDecimal valorTotal) {
this.valorTotal = valorTotal;
}
@NotNull
@Enumerated(EnumType.STRING)
@Column(nullable = false, length = 20)
public StatusEntradaAcidente getStatus() {
return status;
}
public void setStatus(StatusEntradaAcidente status) {
this.status = status;
}
@NotNull
@Enumerated(EnumType.STRING)
@Column(name = "forma_pagamento", nullable = false, length = 20)
public FormaPagamento getFormaPagamento() {
return formaPagamento;
}
public void setFormaPagamento(FormaPagamento formaPagamento) {
this.formaPagamento = formaPagamento;
}
@NotNull
@ManyToOne
@JoinColumn(name = "vendedor_id", nullable = false)
public Usuario getVendedor() {
return vendedor;
}
public void setVendedor(Usuario vendedor) {
this.vendedor = vendedor;
}
@NotNull
@ManyToOne
@JoinColumn(name = "cliente_id", nullable = false)
public Cliente getCliente() {
return cliente;
}
public void setCliente(Cliente cliente) {
this.cliente = cliente;
}
@ManyToOne
@JoinColumn(name = "ocorrencia_id", nullable = false)
public Ocorrencia getOcorrencia() {
return ocorrencia1;
}
public void setOcorrencia(Ocorrencia ocorrencia) {
this.ocorrencia1 = ocorrencia;
}
@OneToMany(mappedBy = "entradaAcidente", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
public List<ItemDespesa> getItens() {
return itens;
}
public void setItens(List<ItemDespesa> itens) {
this.itens = itens;
}
@Transient
public boolean isNovo() {
return getId() == null;
}
@Transient
public boolean isExistente() {
return !isNovo();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
EntradaAcidente other = (EntradaAcidente) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
@Transient
public BigDecimal getValorSubtotal() {
return this.getValorTotal().subtract(this.getValorDesconto());
}
public void recalcularValorTotal() {
BigDecimal total = BigDecimal.ZERO;
total = total.subtract(this.getValorDesconto());
for (ItemDespesa item : this.getItens()) {
if (item.getDespesa() != null && item.getDespesa().getId() != null) {
total = total.add(item.getValorTotal());
}
}
this.setValorTotal(total);
}
public void adicionarItemVazio() {
if (this.isOrcamento()) {
Despesa despesa = new Despesa();
ItemDespesa item = new ItemDespesa();
item.setDespesa(despesa);
item.setEntradaAcidente(this);
this.getItens().add(0, item);
}
}
@Transient
public boolean isOrcamento() {
return StatusEntradaAcidente.ORCAMENTO.equals(this.getStatus());
}
public void removerItemVazio() {
ItemDespesa primeiroItem = this.getItens().get(0);
if (primeiroItem != null && primeiroItem.getDespesa().getId() == null) {
this.getItens().remove(0);
}
}
@Transient
public boolean isValorTotalNegativo() {
return this.getValorTotal().compareTo(BigDecimal.ZERO) < 0;
}
@Transient
public boolean isEmitido() {
return StatusEntradaAcidente.EMITIDO.equals(this.getStatus());
}
@Transient
public boolean isNaoEmissivel() {
return !this.isEmissivel();
}
@Transient
public boolean isEmissivel() {
return this.isExistente() && this.isOrcamento();
}
@Transient
public boolean isCancelavel() {
return this.isExistente() && !this.isCancelado();
}
@Transient
private boolean isCancelado() {
return StatusEntradaAcidente.CANCELADO.equals(this.getStatus());
}
@Transient
public boolean isNaoCancelavel() {
return !this.isCancelavel();
}
@Transient
public boolean isAlteravel() {
return this.isOrcamento();
}
@Transient
public boolean isNaoAlteravel() {
return !this.isAlteravel();
}
@Transient
public boolean isNaoEnviavelPorEmail() {
return this.isNovo() || this.isCancelado();
}
}
Classe onde está o método para download:
@Named
@ViewScoped
public class PesquisaEntradaAcidentesBean implements Serializable {
private static final long serialVersionUID = 1L;
@Inject
private EntradaAcidentes entradas;
private AcidenteFilter filtro;
private List<EntradaAcidente> entradasFiltradas;
private EntradaAcidente entradaSelecionada;
public PesquisaEntradaAcidentesBean() {
filtro = new AcidenteFilter();
entradasFiltradas = new ArrayList<>();
}
public void pesquisar() {
entradasFiltradas = entradas.filtrados(filtro);
}
public StatusEntradaAcidente[] getStatuses() {
return StatusEntradaAcidente.values();
}
public List<EntradaAcidente> getEntradasFiltradas() {
return entradasFiltradas;
}
public AcidenteFilter getFiltro() {
return filtro;
}
public EntradaAcidente getEntradaSelecionada() {
return entradaSelecionada;
}
public void setEntradaSelecionada(EntradaAcidente entradaSelecionada) {
this.entradaSelecionada = entradaSelecionada;
}
public String downloadComprovante() throws IOException {
String nomeArquivo = "comprovante_" + entradaSelecionada.getId() + ".pdf";
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
externalContext.responseReset();
externalContext.setResponseContentType("application/pdf");
externalContext.setResponseHeader("Content-Disposition", "attachment; filename=\"" + nomeArquivo + "\"");
OutputStream out = externalContext.getResponseOutputStream();
try (InputStream is = new ByteArrayInputStream(entradaSelecionada.getComprovante())) {
int read = -1;
byte[] buffer = new byte[1024];
while ((read = is.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
}
facesContext.responseComplete();
return nomeArquivo;
}
}
jsf:
<ui:composition template="/WEB-INF/template/LayoutPadrao.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<ui:define name="titulo">Pesquisa de acidentes</ui:define>
<ui:define name="corpo">
<h:form>
<h1>Pesquisa de acidentes</h1>
<p:toolbar style="margin-top: 20px">
<p:toolbarGroup>
<p:commandButton value="Pesquisar"
action="#{pesquisaEntradaAcidentesBean.pesquisar}" update="@form" />
</p:toolbarGroup>
<p:toolbarGroup align="right">
<p:button value="Novo" outcome="/entradasAcidente/CadastroEntradaAcidente" />
</p:toolbarGroup>
</p:toolbar>
<p:panelGrid columns="2" id="painel"
style="width: 100%; margin-top: 20px" columnClasses="rotulo, campo">
<p:outputLabel value="Número" />
<h:panelGroup>
<p:inputText size="10"
value="#{pesquisaEntradaAcidentesBean.filtro.numeroDe}" />
<p:inputText size="10"
value="#{pesquisaEntradaAcidentesBean.filtro.numeroAte}" />
</h:panelGroup>
<p:outputLabel value="Data de criação" />
<h:panelGroup>
<p:calendar size="10" pattern="dd/MM/yyyy"
value="#{pesquisaEntradaAcidentesBean.filtro.dataCriacaoDe}" />
<p:calendar size="10" pattern="dd/MM/yyyy"
value="#{pesquisaEntradaAcidentesBean.filtro.dataCriacaoAte}" />
</h:panelGroup>
<p:outputLabel value="Responsável" />
<p:inputText size="40"
value="#{pesquisaEntradaAcidentesBean.filtro.nomeVendedor}" />
<p:outputLabel value="Cliente" />
<p:inputText size="40"
value="#{pesquisaEntradaAcidentesBean.filtro.nomeCliente}" />
<p:outputLabel value="Status" />
<p:selectManyCheckbox
value="#{pesquisaEntradaAcidentesBean.filtro.statuses}">
<f:selectItems value="#{pesquisaEntradaAcidentesBean.statuses}"
var="status" itemValue="#{status}" itemLabel="#{status.descricao}" />
</p:selectManyCheckbox>
</p:panelGrid>
<p:dataTable id="acidentesTable"
value="#{pesquisaEntradaAcidentesBean.entradasAcidenteFiltrados}"
var="entrada_acidente" style="margin-top: 20px"
emptyMessage="Nenhum encontrado." rows="20" paginator="true"
paginatorAlwaysVisible="false" paginatorPosition="bottom">
<p:column headerText="Número"
style="text-align: center; width: 100px">
<h:outputText value="#{entrada_acidente.id}" />
</p:column>
<p:column headerText="Cliente">
<h:outputText value="#{entrada_acidente.cliente.nome}" />
</p:column>
<p:column headerText="Ocorrencia">
<h:outputText value="#{entrada_acidente.ocorrencia.descricao}" />
</p:column>
<p:column headerText="Responsável">
<h:outputText value="#{entrada_acidente.vendedor.nome}" />
</p:column>
<p:column headerText="Data de criação"
style="text-align: center; width: 140px">
<h:outputText value="#{entrada_acidente.dataCriacao}">
<f:convertDateTime pattern="dd/MM/yyyy" />
</h:outputText>
</p:column>
<p:column headerText="Valor total"
style="text-align: right; width: 120px">
<h:outputText value="#{entrada_acidente.valorTotal}">
<f:convertNumber type="currency" />
</h:outputText>
</p:column>
<p:column headerText="Status" style="width: 100px">
<h:outputText value="#{entrada_acidente.status.descricao}" />
</p:column>
<p:column headerText="Arquivo">
<h:outputText value="#{entrada_acidente.fileName}" />
</p:column>
<p:column headerText="Download">
<h:commandButton
action="#{pesqusaEntradaAcidentesBean.downloadComprovante}">
<f:setPropertyActionListener
target="#{pesqusaEntradaAcidentesBean.entradaSelecionada}"
value="entrada_acidente.id" />
<f:param name="entrada_acidente" value="#{entrada_acidente.id}" />
</h:commandButton>
</p:column>
<p:column style="text-align: center; width: 50px">
<p:button icon="ui-icon-pencil" title="Editar"
outcome="/entradasAcidente/CadastroEntradaAcidente">
<f:param name="entrada_acidente" value="#{entrada_acidente.id}" />
</p:button>
</p:column>
</p:dataTable>
</h:form>
</ui:define>
</ui:composition>
