Exemplo Prático de utilização da biblioteca Jakarta FileUpload

13 respostas
M

Eu baixei, li a documentação, o tão dito e explicado user guide do Jakarta FileUpload do Apache mas não sei ainda como utilizá-lo numa servlet.

Minha aplicação segue o padrão MVC e minhas servlets de atualização de banco tem a seguinte composição base:

package servlets;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import classesbase.*;
import DAO.*;

public class ServletSomos extends HttpServlet {

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        request.setCharacterEncoding("UTF-8");
        PrintWriter out = response.getWriter();

        String cmd = request.getParameter("cmd");
        if(cmd == null) cmd = "principal";

        SomosDAO somDAO;
        Somos som = new Somos();
        if(cmd!=null || !cmd.equalsIgnoreCase("principal")){
            try {
                som.setId(1);
                som.setTitulo(request.getParameter("titulo"));
                som.setConteudo(request.getParameter("conteudo"));
                // som.setImagem(request.getParameter("imagem"));     
                som.setFuncionario(request.getParameter("funcionario"));
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }

        try{
            somDAO = new SomosDAO();
            RequestDispatcher rd = null;
            if(cmd.equalsIgnoreCase("atu")){

                som = somDAO.ProcurarSomos(1);
                request.setAttribute("som", som);
                rd = request.getRequestDispatcher("admin/atuSomos.jsp");

            }else if(cmd.equalsIgnoreCase("atualizar")){

                somDAO.Atualizar(som);
                request.setAttribute("som", som);
                rd = request.getRequestDispatcher("ServletSomos?cmd=atu");

            }else if(cmd.equalsIgnoreCase("publico")){

                som = somDAO.ProcurarSomos(1);
                som.setConteudo(som.getConteudo().replaceAll("\\n\\r","<br><br>"));
                som.setConteudo(som.getConteudo().replaceAll("  ","&nbsp;&nbsp;"));
                request.setAttribute("som", som);
                rd = request.getRequestDispatcher("publico/somos.jsp");

            }
            rd.forward(request, response);

        }catch(Exception e){
            e.printStackTrace();
            throw new ServletException(e);
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }

}

Alguem pode me ajudar a como utilizar o FileUpload do Jakarta neste padrão de Servlet?
Desde já agradeço.

13 Respostas

M

Assim como ocorrido no tópico que criei de Geração de Relatórios em JPEG com JasperReport, [url]http://www.guj.com.br/posts/list/75418.java[/url], eu consegui achar a solução antes de uma resposta com esta aqui no fórum, e estou deixando aqui um exemplo realmente prático de utilização de FileUpload com Jakarta ao invés de simplesmente falar que ele é fácil.

Agradeço de coração àqueles que colaboraram nos outros tópicos com ajudas que me levaram a muitas reflexões como Puka, o Furutani e o Leogazio!

Para estas pessoas e para as que procuram por uma maneira mais fácil de programar aí vai o código fornecido pelo Christiano Rodarte Vale no site [url]http://www.devmedia.com.br/articles/viewcomp.asp?comp=3572&hl=[/url]!

Download do FileUpload 1.1.1

[url]http://jakarta.apache.org/commons/fileupload/index.html[/url]

Download do org.apache.commons.io (macete que aprendi por fora - PACOTE REQUERIDO)

[url]http://www.java2s.com/Code/Jar/Apache-Common/Downloadcommonsio132jar.htm[/url]

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:/" style="position:absolute; top:23px; left:12px;  width:500px; ">

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

</form>

Criando o Servlet

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.inserirImagemDiretorio(item);
                            }
                        }
                    }
                } catch (FileUploadException ex) {
                       ex.printStackTrace();
                } catch (Exception ex) {
                       ex.printStackTrace();
                }
            }
    }

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

}

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

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;
    }

Esta é a seleção que eu usei do Christiano Rodarte Vale. O artigo na íntegra se encontra no site citado acima. Conforme mencionado no inínio desta mensagem, a biblioteca Jakarta FileUpload precisa de uma outra biblioteca para funcionar: a org.apache.commons.io. Para o correto funcionamento da Jakarta FileUpload é [color=red]NECESSÁRIO O DOWNLOAD DA ORG.APACHE.COMMONS.IO[/color]!!

Este exemplo é um ótimo "osso" que pode ser customizado para qualquer necessidade!!

Abraços!!!

J

Ressuscitando o tópico…

Não consegui fazer esse exemplo funcionar, quando clico em “Enviar Dados” ele nem chama a classe. =/

M

Vale lembrar que com a última atualização deste fórum, alguns problemas vieram a alterar alguns cases do código. Experimente consertar o action do form de envio do arquivo para PascalCase: ServletUpload. Deve ter outros erros semelhantes no meio da programação, faça a análise deles.

jessicabnu:
Ressuscitando o tópico…

Não consegui fazer esse exemplo funcionar, quando clico em “Enviar Dados” ele nem chama a classe. =/

J

Sou novata em jsf, estou vendo agora sobre upload mas estou bem perdida.

Tem muitas classes que não conheço, e vou procurando aos poucos.

Então se você puder me ajudar com o código, com o que mudar, acrescentar, ficarei grata =]

M

Você está começando agora a programar pra web? Eu escrevi um artigo no meu site sobre como programar pra web pra quem tá iniciando. Com o conhecimento que vc pegará nele, você poderá ver este tutorial com mais tranquilidade.

O endereço do artigo é www.sistemaseweb.com.br/javaweb

Qualquer dúvida sobre o artigo, meu e-mail se encontra na área do autor.

L

MRapha, o link que você mandou está fora.

Teria outra forma de lê-lo?

Obrigado

M

Aconteceu um problema ao ser trocado o meu servidor, então esqueci de subir ao ar este artigo. Obrigado por ter me lembrado deste problema. Vou subí-lo já.

T

Olá pessoal,

Fiz minha aplicação que contém envio de arquivos, me baseei código deste exemplo, mas precisei fazer algumas modificações, pois, meu método de gravação do caminho da imagem é feito no padrão MVC e DAO.

Assim, não estou sabendo como fazer para gravar no banco, para ele pegar o objeto do tipo File para passar para o meu método.

Classe PostgreUsuarioDAO:

public Usuario alterarImagem(Usuario usu) {
        StringBuffer sql = new StringBuffer("");

        sql.append("UPDATE usuario ");
        sql.append("SET imagem = ? ");
        sql.append("WHERE username = ?");

        Connection cn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;

        try {
            cn = PostgreDAOFactory.createConnection();
            ps = cn.prepareStatement(sql.toString());
            ps.setString(1, usu.getImagem());
            ps.setString(2, usu.getUsername());

            rs = ps.executeQuery();

            if (rs.next()) {
                return this.populaUsuario(rs);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (rs != null) {
                try {
                    rs.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (ps != null) {
                try {
                    ps.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (cn != null) {
                try {
                    cn.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        return usu;
    }

    public ImageIcon recuperarImagemDiretorio(String username) {
        StringBuffer sql = new StringBuffer("");

        sql.append("SELECT imagem FROM usuario ");
        sql.append("WHERE username = ?");

        Connection cn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;

        ImageIcon imagem = null;

        try {
            cn = PostgreDAOFactory.createConnection();
            ps = cn.prepareStatement(sql.toString());
            ps.setString(1, username);

            rs = ps.executeQuery();

            if (rs.next()) {
                String caminhoImagem = rs.getString("imagem");
                if (caminhoImagem != null) {
                    imagem = new ImageIcon(caminhoImagem);
                }
            }
        } catch (SQLException ex) {
            ex.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (rs != null) {
                try {
                    rs.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (ps != null) {
                try {
                    ps.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (cn != null) {
                try {
                    cn.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        return imagem;
    }

Classe UploadServlet:

private void inserirImagemDiretorio(FileItem item) throws Exception {
        //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();
    }

    protected 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.inserirImagemDiretorio(item);
                        }
                    }
                }
            } catch (FileUploadException ex) {
                ex.printStackTrace();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }

Como eu chamo pra executar o insert no meu servlet?

M

Eu tenho um site-artigo sobre desenvolvimento web com mvc e servlets dentro da sessão Aprendiz no meu site (www.sistemaseweb.com.br) que ensina exatamente isso.

Depois de lê-lo, veja se a dúvida ainda persiste e retorne aqui.

Abraços!

T

Então,

Na verdade meu problema tá em, ao invés de fazer isso, no servlet:

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();  
            }  
    }

Quero fazer isso na minha classe PostgreUsuarioDAO, um método só pra isso.
Ae, não sei como pegar esse objeto do tipo File e conseguir mandar ele pra gravar através do meu método na classe PostgreUsuarioDAO

Agradeço pela ajuda
Abraço

T

Alguém?

T

Alguém ae pode me ajudar??? :roll:

T

???

Criado 8 de janeiro de 2009
Ultima resposta 7 de nov. de 2011
Respostas 13
Participantes 4