Download via FTP em JSF

135 views
Skip to first unread message

Marcelo Gomes

unread,
Feb 7, 2016, 2:21:56 PM2/7/16
to javasf: JavaServer Faces Group
Pessoal

Estou armazenando documentos que são enviados pela minha aplicação para um servidor de ftp.

O envio está sendo feito corretamente, mas agora eu preciso fazer o download.

Pesquisei e encontrei algumas classes. Mas não está funcionando corretamente.

Alguém tem um exemplo prático de como fazer isso?

Não gostaria de expor a url do servidor para o download.

Desde já agradeço toda a ajuda.

Abraços
Marcelo

Nilson Uehara

unread,
Feb 10, 2016, 5:43:35 AM2/10/16
to Grupo JSF
Já viu este artigo do Rafael Ponte? 


Um abraço,
Nilson Uehara

--
Você recebeu essa mensagem porque está inscrito no grupo "javasf: JavaServer Faces Group" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para javasf+un...@googlegroups.com.
Acesse esse grupo em https://groups.google.com/group/javasf.
Para ver essa discussão na Web, acesse https://groups.google.com/d/msgid/javasf/636d977f-e317-4989-b823-db0e33922fb1%40googlegroups.com.
Para mais opções, acesse https://groups.google.com/d/optout.

Ricardo Johannsen

unread,
Feb 11, 2016, 9:55:30 AM2/11/16
to javasf: JavaServer Faces Group
Oi ,segue meu código de download via ftp utilizando a biblioteca commons-email:

como eu uso zk e o componente FileDoenload recebe um input stream eu tive que converter um output em um input, mas dependendo do seu caso é só retornar o outputStream direto 

public  InputStream  downloadArquivo2(String nomeArquivo, String nomePasta,String mimeType) throws Exception{
if(mimeType == null){
mimeType = "application/pdf";
}
FTPClient ftp = new FTPClient();  
InputStream  in = null;
ByteArrayOutputStream baos = null;
try{
ftp.connect( "ipdoservidor",porta );   
if( FTPReply.isPositiveCompletion( ftp.getReplyCode() ) ) {  
ftp.login( "logindoftp", "senhadoftp" );  
} else {  
ftp.disconnect();  
throw new Exception("Não Foi Possível Estabelecer Uma Conexão com o Servidor de Arquivos!!");
}  
boolean exists =  ftp.changeWorkingDirectory (nomePasta); 
if(exists){  
ftp.setFileType( FTPClient.BINARY_FILE_TYPE );  
    baos = new ByteArrayOutputStream();  
ftp.retrieveFile(nomeArquivo, baos); 
in = new ByteArrayInputStream (baos.toByteArray());
}else{
throw new Exception("erro no download!");
}
}finally{
if(baos != null){
baos.close();
}
if(in != null){
in.close();
}
           ftp.disconnect();
}
return in;
}

Marcelo Gomes

unread,
Feb 12, 2016, 8:25:25 AM2/12/16
to javasf: JavaServer Faces Group
Nilson
Eu li, mas não funcionou.
Outro problema é que os anexos possuem os mais diversos tipo de extensões.
Tentei usar o <p:fileDownload> do primefaces, também sem sucesso.

Nilson Uehara

unread,
Feb 12, 2016, 8:29:03 AM2/12/16
to Grupo JSF
Um detalhe que pode ser útil.
Para usar o <p:fileDownload> o managedBean deve estar no escopo de sessão (pelo menos eu nunca consegui fazer funcionar em escopos menores)

Um abraço,
Nilson Uehara

Marcelo Gomes

unread,
Feb 12, 2016, 8:42:53 AM2/12/16
to javasf: JavaServer Faces Group
Nilson
Ele está, mas ao tentar usá-lo e dá um refesh e não executa.
Eu criei uma MB exclusivo para isso. A propriedade ajax está "ajax=false" e nada.
O upload vai de boa, inclusive gravando via ftp, mas na hora da volta..... 
Valeu

Nilson Uehara

unread,
Feb 12, 2016, 8:46:38 AM2/12/16
to Grupo JSF
Coloque o seu código ai pra gente ajudar... vai ver é alguma coisa que passou batido.

Um abraço,
Nilson Uehara

Marcelo Gomes

unread,
Feb 12, 2016, 11:09:46 AM2/12/16
to javasf: JavaServer Faces Group
Nilson

Segue:

Meu xhtml:

<p:commandButton icon="fa fa-fw fa-download" title="Download" ajax="false"  >
    <f:setPropertyActionListener value="#{anexo.nomeAnexo}" target="#{downloadAtividadeAnexoBean.nomeAnexo}" />
    <f:setPropertyActionListener value="#{cadastroAtividadeBean.codigoAtividade}" target="#{downloadAtividadeAnexoBean.pasta}" />
    <p:fileDownload value="#{downloadAtividadeAnexoBean.arquivoDownload}"></p:fileDownload>
</p:commandButton>


Meu bean:

package com.porto.npf.sgpsweb.controller;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.Serializable;

import javax.faces.bean.SessionScoped;
import javax.inject.Named;

import org.apache.log4j.Logger;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;

import com.porto.npf.sgpsweb.common.SGPSConstants;
import com.porto.npf.sgpsweb.util.MGUtils;

@Named
@SessionScoped
public class DownloadAtividadeAnexoBean implements Serializable {
private static final long serialVersionUID = 1L;
private Logger logger = Logger.getLogger(DownloadAtividadeAnexoBean.class.getName());
private StreamedContent arquivoDownload;
private String nomeAnexo;
private String pasta;
private Integer tabIndex;
    
    public DownloadAtividadeAnexoBean(){    
    }
    
    public void download() throws FileNotFoundException {
    String nomeArquivo =  MGUtils.getRealPath("DOCS")  + "/" + this.nomeAnexo;
   
    logger.info("Arquivo : " + this.nomeAnexo);
   
   
    if ("LOCAL".equals(SGPSConstants.AMBIENTE)) {
    nomeArquivo = "c:\\workspace3\\sgps-primefaces\\src\\main\\webapp\\documentos\\" + nomeAnexo;
    } else {
    nomeArquivo = "/opt/repo/documentos/" + pasta + "/" + nomeAnexo;
    }
   
    this.tabIndex = 2;
   
    // pega a extensao do arquivo
    String extensao = "";
    if (this.nomeAnexo.endsWith(".zip")) {
    extensao = "zip";
    } else if (this.nomeAnexo.endsWith(".pdf")) {
    extensao = "pdf";
    } else if (this.nomeAnexo.endsWith(".docx")) {
    extensao = "docx";
    } else if (this.nomeAnexo.endsWith(".jpg")){
    extensao = "jpg";
    } else if (this.nomeAnexo.endsWith(".xls")){
    extensao = "xls";
    } else if (this.nomeAnexo.endsWith("*.xlsx")){
    extensao = "xlsx";
    } else if (this.nomeAnexo.endsWith(".ppt")) {
    extensao = "ppt";
    } else if (this.nomeAnexo.endsWith(".pptx")) {
    extensao = "pptx";
    }
   
        InputStream stream = new FileInputStream(nomeArquivo);    
        this.arquivoDownload = new DefaultStreamedContent(stream, "application/"+extensao, nomeAnexo);
    }

public StreamedContent getArquivoDownload() {
return arquivoDownload;
}


public void setArquivoDownload(StreamedContent arquivoDownload) {
this.arquivoDownload = arquivoDownload;
}


public String getNomeAnexo() {
return nomeAnexo;
}


public void setNomeAnexo(String nomeAnexo) {
logger.info("Nome do arquivo recebido : " + nomeAnexo);
this.nomeAnexo = nomeAnexo;
}

public Integer getTabIndex() {
return tabIndex;
}

public void setTabIndex(Integer tabIndex) {
this.tabIndex = tabIndex;
}

/**
* @return the pasta
*/
public String getPasta() {
return pasta;
}

/**
* @param pasta the pasta to set
*/
public void setPasta(String pasta) {
this.pasta = pasta;
}
}

Henrique Neto

unread,
Feb 12, 2016, 11:40:47 AM2/12/16
to jav...@googlegroups.com
Eu uso o fileDownload e até agora nao tive problemas. Uso inclusive com MB ViewScoped.
Utilizo da Seguinte forma:
No XHTML:
Imagem inline 4

No MB:
Imagem inline 6

Modifiquei apenas pra ocultar a regra de negocio que uso mas basicamente é isso.
Veja se isso te ajuda.

Att.,
Henrique Neto
Graduado em Análise e Desenvolvimento de Sistemas
Pós-Graduando em Engenharia de Software
LPIC-1 -  ID: LPI000243620 Verification: tmlvhgun7h
Oracle Certified Java Programmer 6
"Dizem que o tempo muda tudo, mas não é verdade. Fazer coisas é que muda
algo, não fazer nada deixa as coisas do jeito que estão."
Gregory House


Henrique Neto

unread,
Feb 12, 2016, 11:43:03 AM2/12/16
to jav...@googlegroups.com
Ah.
Algo que pode fazer a diferença é utilizar o onclick="PrimeFaces.monitorDownload(start, stop);" no commandButton.
Veja se esse é seu problema.

Att.,
Henrique Neto
Graduado em Análise e Desenvolvimento de Sistemas
Pós-Graduando em Engenharia de Software
LPIC-1 -  ID: LPI000243620 Verification: tmlvhgun7h
Oracle Certified Java Programmer 6
"Dizem que o tempo muda tudo, mas não é verdade. Fazer coisas é que muda
algo, não fazer nada deixa as coisas do jeito que estão."
Gregory House


Marcelo Gomes

unread,
Feb 12, 2016, 12:31:29 PM2/12/16
to javasf: JavaServer Faces Group
Henrique
Segui todos os passos, mas continuo com problemas.

O novo bean conforme sua sugestão. Uma diferença é que o InputStream veio de uma classe "download", pois vem de um ftp.
No xthml eu implementei da forma sugerida.
Mas mesmo assim, dá refresh na tela como se fosse um submit.

    /**
     * Faz o downloado do arquivo
     * @param nome
     * @return
     */
    public StreamedContent baixarArquivo(String nome) {
    StreamedContent file = null;
    String extensao = "application/pdf";
    byte[] arquivoByte = null;
    InputStream inputStream = FTPTransfer.download("6143703.pdf", "documentos", "PED4");
    file = new DefaultStreamedContent(inputStream,extensao,nome);
    return file;
    }

<p:commandButton icon="fa fa-fw fa-download" title="Download" ajax="false"  
    onclick="Primefaces.monitorDownload(start, stop);" immediate="true">
    <p:fileDownload value="#{downloadAtividadeAnexoBean.baixarArquivo(anexo.nomeAnexo)}" />
</p:commandButton>


/**
 * Faz a recuperação do arquivo
 * @param nomeArquivo
 * @param directoryWork
 * @param pasta
 * @return
 */
public static InputStream download(String nomeArquivo, String directoryWork,
String pasta) {
        FTPClient ftp = new FTPClient();
InputStream arqRetorno = null;
try {
          ftp.connect(SGPSConstants.IP_SERVIDOR_FTP);
ftp.login(SGPSConstants.USER_FTP, SGPSConstants.SENHA_FTP);
ftp.changeWorkingDirectory("/opt/repo" + directoryWork + "/"
+ pasta + "/");
String[] arq = ftp.listNames();
String url = "/opt/repo" + directoryWork + "/" + pasta + "/"
+ nomeArquivo;
FileOutputStream fos = new FileOutputStream(url);
if (ftp.retrieveFile(nomeArquivo, fos)) {
arqRetorno = ftp.retrieveFileStream("/opt/repo/documentos/fotos/" + nomeArquivo);
System.out.println("Download efetuado com sucesso!");
} else {
System.out.println("Erro ao efetuar download do arquivo.");
}
} catch (IOException e) {
e.printStackTrace();
}
return arqRetorno;
}

Henrique Neto

unread,
Feb 12, 2016, 12:42:57 PM2/12/16
to jav...@googlegroups.com
Marcelo,

2 perguntas:

* Debugando, o FTP está retornando o arquivo corretamente? InputStream não está nulo?

* Faz um teste apontando pra um arquivo local. Pode ser HardCoded mesmo só pra verificar se o problema está no FTP ou no método q retorna o arquivo.



Att.,
Henrique Neto
Graduado em Análise e Desenvolvimento de Sistemas
Pós-Graduando em Engenharia de Software
LPIC-1 -  ID: LPI000243620 Verification: tmlvhgun7h
Oracle Certified Java Programmer 6
"Dizem que o tempo muda tudo, mas não é verdade. Fazer coisas é que muda
algo, não fazer nada deixa as coisas do jeito que estão."
Gregory House


Everton Fujimoto

unread,
Feb 12, 2016, 1:39:39 PM2/12/16
to jav...@googlegroups.com
Olhando o seu código, vou te dar algumas sugestões (mas eu nunca utilizei o p:fileDownload, geralmente eu pego o outputstream e envio direto):

1. O DefaultStreamedContent faz o "cache" do arquivo em memória? Imagino que não... se não faz você tem que (uma das opções): 
1.1 Instanciar o InputStream na mesma requisição que está sendo baixado o arquivo, pois o InputStream estará lendo um canal de dados diretamente a partir do disco rígido que tem chance de já estar fechado. (ou seja, pode implementar essa regra diretamente no getter)
1.2 Copiar os bytes do inputstream para um ByteArrayInputStream (um InputStream que trabalha a partir de um array de bytes na memória)

2. onde está sendo chamado o método download que popula o StreamedContent?


Att.

Everton William Fujimoto
Tecnólogo em Processamento de Dados - Fatec-SO
Especialista em Gestão de Projetos de Software - IGTI
Mestrando em Administração - UFSC
OCAJP, OCPJP, OCEWCD, OCEWSD, OCEJPA, OCEEJB, OCEJSF, 1Z0-807, OCE SQL Expert

Reply all
Reply to author
Forward
0 new messages