Obrigado por visitar a devmedia.com.br!

Precisamos de você para divulgar nossos vídeos e cursos gratuitos para a comunidade.

Se você gosta da devmedia.com.br por favor dê-nos o seu clique para o Google+ e ajude outros desenvolvedores ao redor do mundo.



Obrigado por seu apoio!
Equipe DevMedia

sair sem compartilhar (x)
DevMedia - asp.net, Java, Delphi, SQL e web Design, tudo em um só lugar!
Bem vindo a DevMedia!
LOGIN:     SENHA:

Upload de arquivos usando Commons-FileUpload

Neste tutorial, mostrarei como se faz para enviar arquivos para um servidor através de uma aplicação Web, utilizando o Commons-FileUpload da Jakarta.

Introdução
Neste tutorial, mostrarei como se faz para enviar arquivos para um servidor através de uma aplicação Web, utilizando o Commons-FileUpload da Jakarta. Serão mostradas duas maneiras de se fazer isso:

1 – Enviar uma imagem para o servidor guardando-a em um campo BLOB do Banco de Dados;

2 – Enviar uma imagem para o servidor, guardá-la em um diretório e armazenar seu endereço no Banco de Dados;

Visão Geral
A API Commons FileUpload tornou fácil e robusta a capacidade de realizar Uploads através de seus Servlets e aplicações Web.

FileUpload analisa gramaticalmente as requisições HTTP conforme RFC 1867 (http://www.ietf.org/rfc/rfc1867.txt) "Form-based File Upload in HTML". Isto quer dizer que, se uma requisição http for submetida usando um método POST, a partir de um formulário tipo "multipart/form-data", então FileUpload pode analisar gramaticalmente esse pedido, e retornar os resultados de maneira fácil para o método que o chamou.

Download do FileUpload 1.1.1

Commons-FileUpload pode ser baixado a partir do endereço:
http://jakarta.apache.org/commons/fileupload/index.html

Após fazer o download e extrair os arquivos, adicione o commons-fileupload-1.1.1.jar ao seu projeto.

Documentação
Neste tutorial procuraremos dar mais atenção à codificação do que à teoria. Uma documentação completa sobre o Commons-FileUpload pode ser encontrada em:
http://jakarta.apache.org/commons/fileupload/using.html

http://jakarta.apache.org/commons/fileupload/apidocs/index.html

e, também no pacote FileUpload 1.1.1.zip

Definindo um formulário para o envio do arquivo
Como exemplo, vamos fazer o upload de uma imagem para o servidor. Um formulário simples deve ser criado em HTML para levar a imagem até nossa aplicação. Este formulário deve obrigatoriamente ser do tipo “multipart/form-data":

<form id="formImagem" name="formImagem" method="post" action="servletupload" enctype="multipart/form-data">

<input type="hidden" id="tipoForm" name="tipoForm" value="imagem">

<input name="imagem" type="file" accept="image/jpeg; image/gif; image/bmp; image/png" id="imagem" class="dados" maxlength="60" tabindex="1" value="c:/" position:absolute; top:23px; left:12px;  width:500px; ">

<input type="submit" id="upload" name="upload" tabindex="2" position:absolute; top:20px; left:532px; >

 

</form>

 

Criando o Servlet

Agora vamos criar um Servlet para receber esta requisição:

 

import org.apache.commons.fileupload.servlet.ServletFileUpload;

import org.apache.commons.fileupload.disk.DiskFileItemFactory;

import org.apache.commons.fileupload.FileUpload;

import org.apache.commons.fileupload.FileItemFactory;

import org.apache.commons.fileupload.FileItem;

import org.apache.commons.fileupload.FileUploadException;

 

public class ServletUpload extends HttpServlet{

 

    //Initialize global variables

    public void init() throws ServletException {

    }

 

    //Process the HTTP Post request

    public void doPost(HttpServletRequest request, HttpServletResponse response)

                       throws ServletException, IOException {

        doGet(request, response);

    }

 

//Process the HTTP Get request

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

 

            boolean isMultiPart = FileUpload.isMultipartContent(request);

            if (isMultiPart) {

                FileItemFactory factory = new DiskFileItemFactory();

                ServletFileUpload upload = new ServletFileUpload(factory);

                String formulario = "";

                try {

                    List items = upload.parseRequest(request);

                    Iterator iter = items.iterator();

                    while (iter.hasNext()) {

                        FileItem item = (FileItem) iter.next();

                        if (item.getFieldName().equals("tipoForm")) {

                            formulario = item.getString();

                        }

                        if (!item.isFormField()) {

                            if (item.getName().length() > 0) {

                                this.inserirImagem(item);

                            }

                        }

                    }

                }

catch (FileUploadException ex) {

   ex.printStackTrace();

                }

catch (Exception ex) {

   ex.printStackTrace();

                }

            }

    }

   // implementação de demais métodos do Servlet.

}

 

Inserindo e recuperando a Imagem em um Campo Blob

Se você analisou o código do Servlet acima, deve ter notado a chamada ao método inserirImagem(item) que ainda não foi implementado. Pois bem, iremos agora escrever este método que irá inserir a imagem em um campo Blob do banco de dados. Para este exemplo eu usei o MySql.

 

A estrutura e criação da tabela deste exemplo são:

 

TabelaTeste

Codigo (Integer)

Imagem (Blob)

 

CREATE TABLE TabelaTeste (

      codigo                  INT UNSIGNED NOT NULL,

      imagem            BLOB NOT NULL

);

 

A seguir a implementação do método inserirImagem(FileItem item):

 

     /**

     * @param item FileItem, representa um arquivo que é enviado pelo formulario

     * MultiPart/Form-data

     * @throws IOException

     * @throws ServletException

     */

    private  void inserirImagem(FileItem item) {

     

Connection conexao = null;

 

/**

 

  Estabeleça a conexão

 

*/

 

      PreparedStatement declaracao = null;

 

            String sql = "INSERT INTO TabelaTeste (codigo, imagem) VALUES(?, ?)

                         ";

 

try {

                  declaracao = conexao.prepareStatement(sql);

            declaracao.setInt(1, 1); // codigo 1

                 declaracao.setBinaryStream(2, item.getInputStream(),

                                           (int) item.getSize() );

                  declaracao.executeUpdate();

 

             } catch (SQLException ex) {

                        ex.printStackTrace();

            } catch (Exception ex) {

                  ex.printStackTrace();

            }

}

 

A seguir, o método recuperaImagem() mostra como fazer para recuperar esta imagem que foi inserida no Banco de Dados.

 

OBS: importar a classe com.mysql.jdbc.Blob

 

public ImageIcon recuperaImagem() {

 

Connection conexao = null;

 

/**

 

  Estabeleça a conexao

 

*/

 

        Statement declaracao = null;

        ResultSet resultado = null;

        StringBuffer sql = new StringBuffer();

        sql.append("SELECT imagem FROM tabelaTeste WHERE codigo = 1");

        ImageIcon imagem = null;

        try {

            declaracao = conexao.createStatement();

            resultado = declaracao.executeQuery(sql.toString());

 

            if (resultado.next()) {

                Blob blob = (Blob) resultado.getBlob("imagem");

                if (blob!=null){

                    imagem = new ImageIcon(blob.getBytes(1,

                                                        (int) blob.length()));

                }

            }

        } catch (SQLException ex) {

            ex.printStackTrace();

        } catch (Exception ex) {

            ex.printStackTrace();

        }

        return imagem;

    }

 

Gravando e recuperando a Imagem em um diretório do servidor

Os Exemplos acima mostraram como podemos fazer, de maneira bem simples, a inserção e a recuperação de uma imagem para um campo blob do banco de dados.

 

Agora mostraremos uma outra forma de se fazer este upload, porém, vamos gravar a imagem em um diretório do servidor e no banco de dados guardaremos apenas o endereço desta imagem.

 

Usaremos exatamente o mesmo formulário criado (html) e o mesmo método doGet() do Servlet mostrado acima. A única diferença será a chamada ao método que ao invés de ser:
 this.inserirImagem(item);

Será

 this.inserirImagemDiretorio(item);

 

Para isto vamos criar uma outra tabela no Banco de Dados conforme a estrutura a seguir:

 

TabelaTeste2

Codigo (Integer)

Imagem (Varchar)

 

CREATE TABLE TabelaTeste2 (

      codigo                  INT UNSIGNED NOT NULL,

      imagem            VARCHAR (255)

);

 

Agora vamos escrever o método inserirImagemDiretorio(FileItem item) que irá realizar duas tarefas:

 

1 – Guardar a imagem em um diretório do servidor;

2 – Guardar no Banco de dados o endereço para recuperação desta imagem;

 

     /**

     *

     * @param item FileItem, representa um arquivo que é enviado pelo formulario

     * MultiPart/Form-data

     * @throws IOException

     */

    private void inserirImagemDiretorio(FileItem item) throws

                                                         IOException {

 

            //Pega o diretório /logo dentro do diretório atual de onde a

            //aplicação está rodando

            String caminho = getServletContext().getRealPath("/logo")

                             + "/";

     

             // Cria o diretório caso ele não exista

            File diretorio = new File(caminho);

            if (!diretorio.exists()){

                diretorio.mkdir();

            }

 

            // Mandar o arquivo para o diretório informado

            String nome = item.getName();

            String arq[] = nome.split("\\\\");

            for (int i = 0; i < arq.length; i++) {

                nome = arq[i];

            }

 

            File file = new File(diretorio, nome);

            FileOutputStream output = new FileOutputStream(file);

            InputStream is = item.getInputStream();

            byte[] buffer = new byte[2048];

            int nLidos;

            while ((nLidos = is.read(buffer)) >= 0) {

                output.write(buffer, 0, nLidos);

            }

            output.flush();

            output.close();

 

 

//Guarda no banco de dados o endereço para recuperação da imagem

 

Connection conexao = null;

 

/**

 

  Estabeleça a conexão

 

*/

 

      PreparedStatement declaracao = null;

 

            String sql = "INSERT INTO TabelaTeste2 (codigo, imagem) VALUES(?, ?)

                         ";

 

try {

                  declaracao = conexao.prepareStatement(sql);

            declaracao.setInt(1, 1); // codigo 1

                 declaracao.setString(2, caminho);

                   resultado = declaracao.executeUpdate();

             } catch (SQLException sqlEx) {

                        ex.printStackTrace();

            } catch (Exception ex) {

                  ex.printStackTrace();

            }

    }

 

Escrevendo o método recuperarImagemDiretorio():

 

public ImageIcon recuperaImagemDiretorio() {

 

Connection conexao = null;

 

/**

 

  Estabeleça a conexao

 

*/

 

        Statement declaracao = null;

        ResultSet resultado = null;

        StringBuffer sql = new StringBuffer();

        sql.append("SELECT imagem FROM tabelaTeste2 WHERE codigo = 1");

        ImageIcon imagem = null;

        try {

            declaracao = conexao.createStatement();

            resultado = declaracao.executeQuery(sql.toString());

            if (resultado.next()) {

 

String caminhoImagem = resultado.getString("imagem");

 

                if (caminhoImagem!=null){

                    imagem = new ImageIcon(caminhoImagem);

                } 

          }

        } catch (SQLException ex) {

            ex.printStackTrace();

        } catch (Exception ex) {

            ex.printStackTrace();

        }

        return imagem;

    }

 

Conclusão

Vimos como pode ser fácil realizar UpLoads de imagem para um servidor, seja para um campo Blob ou para um diretório qualquer também no servidor.

 

A utilização de qualquer um desses métodos vai depender de suas decisões de projeto analisando qual será a melhor e mais viável alternativa.

 

A recuperação destas imagens pode ser utilizada, por exemplo para exibições em relatórios (conforme mostrei em artigos anteriores), exibição de paginas personalizadas de usuários do sistema, dentre outras.

 

Espero que todos tenham gostado deste tutorial e tirado o maior proveito dele.

 

Um abraço.

Até a próxima!





    25 COMENTÁRIOS

[Fechar]

Este post é fechado - você precisa ter acesso ao post para incluir um comentário.



Keith
nao entendi bem como fazer o download (recuperar) o arquivo do diretorio, ou seja, fazer o inverso, invés do upload quero fazer o download do arquivo.


em 19/5/2007 06:59 - Responder

 

  Jhonnatan
Você quer fazer download ou exibir a imagem no browser para que o usuário possa salvar?


em 23/5/2007 10:33 - Responder
 

Clávison
Muito bom o artigo. Bem explicativo e bem genérico para ser adaptado em várias situações.


em 28/5/2007 13:40 - Responder

 

Rafael
O trecho em JAVA não compila se você não trocar o CAPS das classes e variáveis. O trecho em HTML não fecha corretamente o final de cada tag. O autor poderia ter sido mais cuidadoso ao colar os trechos de código.


em 11/7/2007 17:49 - Responder

 

Marco
Muito bom artigo, mas tenho uma dúvida... Alguém sabe como faço pra obter os valores de outros inputs do formulários HTML?? Além de enviar o arquivo, preciso de receber os dados dos outros componentes do formulário, como os input type=text, etc...


em 24/7/2007 14:28 - Responder

 

Marcos
Otimo tutorial amigo!! Parabens!


em 1/8/2007 09:37 - Responder

 

Edvaldo
Christiano Rodarte Vale Cara funcionou tudo certinho, mais estou com uma dúvida... que seria como vou recuperar obj ImageIco no Jsp. Vc teria algum exemplo para demonstrar?!?!? Muito obrigado pela atenção.


em 6/8/2007 18:08 - Responder

 

Elio
Ótimo tutorial! Parabens pelo trabalho!


em 31/8/2007 01:43 - Responder

 

Felipe
Amigo nao funcionou aqui.. Exception: javax.servlet.ServletException: Error instantiating servlet class upload.servlets.Upload root cause: java.lang.NoClassDefFoundError: org/apache/commons/fileupload/FileUploadException O q poderia ser? Obrigado!!!


em 3/8/2007 09:12 - Responder

 

  Fernando Dalcin
Falta importar a classe org/apache/commons/fileupload/FileUploadException...


em 14/9/2007 20:08 - Responder
 

David
Assim qualquer um escreve artigo... http://commons.apache.org/fileupload/using.html


em 24/10/2007 17:01 - Responder

 

  Eduardo
David, não me parece igual. Este artigo está muito mais explícito.


em 20/11/2007 13:22 - Responder
 

Mirla Braga
É o segundo artigo seu que leio, o primeiro foi sobre jfreeChar, um excelente artigo para se introduzi e começar a desenvolver plotamente de gráficos em java e o segundo foi este sobre Upload de arquivo. Ambos foram esseciais para as atividades que estou desenvolvendo no momento. Obrigada e vc está de parabéns. Sé uma observação, na implementação do exemplo de upload foi necessário mais uma lib (commons-io-1.2.jar http://jakarta.apache.org/site/downloads/downloads_commons-io.cgi ). Ateh o próximo!!!


em 19/7/2007 19:54 - Responder

 

  Eduardo
http://commons.apache.org/downloads/download_io.cgi


em 20/11/2007 13:55 - Responder
 

Amauri
Achei ótimo muito bem explicado, só o que acontece comigo no caso de salvar o caminho da imagem no banco é o seguinte se o usuário mandar uma outra imagem com o mesmo nome no mesmo diretório ele sobrescreve a imagem. como resolver isto.


em 29/2/2008 21:40 - Responder

 

Ivo
Eu não tenho certeza absoluta mas no linux não se pode referenciar a paths com barra pra esquerda "/logo", então o certo seria colocar "\\logo".


em 17/4/2008 08:45 - Responder

 

  Alecindro Steinke Castilho
Eu uso File.separatorChar para obter o caracter separador do computador em que está instado o software


em 14/5/2008 02:46 - Responder
 

Carlos
Quando rodo a aplicação aparece a seguinte mensagem: type Status report message /servidor/ServletUpload description The requested resource /servidor/ServletUpload) is not available.


em 30/5/2008 18:25 - Responder

 

Siomara Cintia Pantarotto

Excelente. Parabéns. Rodou redondo. Seu tutorial, muito embora não seja para 'dummies', está melhor que as explicações do próprio Commons-FileUpdate.

No entanto, como usei a última versão, diferente da que vc usou, precisei alterar a linha:

boolean isMultiPart = FileUpload.isMultipartContent(request); // método deprecado

por:

boolean isMultiPart = ServletFileUpload.isMultipartContent(request);

[]s Siomara



em 3/10/2009 12:37 - Responder

 

Nayara Costa Soares
Implementei o tutorial, deu o seguinte erro: "java.lang.NoClassDefFoundError: org/apache/commons/io/output/DeferredFileOutputStream org.apache.commons.fileupload.disk.DiskFileItemFactory.createItem(DiskFileItemFactory.java:191) org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:350) org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:126) controle.ServletUpload.doGet(ServletUpload.java:52) controle.ServletUpload.doPost(ServletUpload.java:39) javax.servlet.http.HttpServlet.service(HttpServlet.java:710) javax.servlet.http.HttpServlet.service(HttpServlet.java:803)" Acho que importei as classes certas, mas não tenho certeza, todos tiveram que importar essas classes: import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Iterator; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.swing.ImageIcon; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.FileUpload; import org.apache.commons.fileupload.FileItemFactory; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; também importei minha conexão: import persistencia.Conexao;


em 3/10/2007 20:23 - Responder

 

  Nayara Costa Soares
Se alguém puder me ajudar pode me mandar um e-mail para: ncs_nayara@yahoo.com.br


em 3/10/2007 20:25 - Responder
 

  Flavio
OI meu amigo, estou com o mesmo erro, alguem chegou a te ajudar? se sim vc poderia me dar uma mão? flavioanchieta@yahoo.com.br


em 6/11/2007 17:15 - Responder
 

  Eduardo
Você não está importamdo correctamente a biblioteca.


em 20/11/2007 13:24 - Responder
 

  Marcelo Alves
Esta acontecendo o mesmo erro comigo... java.lang.NoClassDefFoundError Importei o .jar para a minha pasta : \build\web\WEB-INF\lib


em 30/5/2008 17:05 - Responder
 

  Lélio José De Souza
Tente adicionar também o commons-io http://commons.apache.org/io/ Comigo funcionou. Todos os meus jar''''s estão no \buil\web\WEB-INF\lib\


em 2/6/2008 14:46 - Responder
 



[Este post ainda não foi associado a uma sequência]
Autor
Christiano Rodarte Vale

Christiano Rodarte Vale (christianovale@gmail.com), 26 anos, formado em Ciência da Computação pela UNIFOR-MG, trabalho como Desenvolvedor de Componentes Web em uma empresa (iTrade – Tecnologia de Informação) que desenvolve soluções para o setor de Agro-Negócio (www.itradeti.com.br).


Space do autor
Estatísticas
Favorito:
Comentários:
Feedback:
Utilidade:
7   1
[Fechar]

Você precisa estar logado para dar um feedback.

Clique aqui para efetuar o login
[Fechar]
Este post está disponível para assinantes da Java Magazine ou para quem possui Créditos DevMedia.

  Conheça os planos de créditos DevMedia e visualize esse post agora mesmo!

Plano conveniência – Neste plano este post custa R$ 0,00 (Compre agora)
Esse plano permite que você compre somente um post, pagando por ele seu preço sem desconto.

Plano ocasional: Aqui este post custa: R$ -1,00 (assinante) ou R$ -1,00 (não-assinante)
Este plano é ideal para quem tem interesse em mais de um post. Você compra um mínimo de R$ 50,00 em créditos e ganha, em média, 50% de desconto no preço do post. Compre Créditos agora!

Assinatura de Créditos (Plano econômico) – Aqui este post custa R$ -1,00
Este plano é ideal para quem tem interesse em muitos posts. Com esse plano você compra R$ 180,00 em créditos e ganha, em média, 80% de desconto no preço do post. Assine este plano agora!

> Saiba mais sobre o Sistema de Créditos DevMedia
web-03
DevMedia  |  Anuncie  |  Fale conosco
Hospedagem web por Porta 80 Web Hosting
2012 - Todos os Direitos Reservados a web-03