Você está na página 1de 9

http://translate.google.com/translate?hl=pt&sl=auto&tl=pt&u=http%3A%2F%2Fwww.

jou
rnaldev.com%2F2573%2Fspring-mvc-file-upload-example-tutorial-single-and-multiple
-files
Como fazer upload e download de arquivos usando Servlet e JSP
By Anderson Vioso de Arajo On 19:13 In Eclipse, EL, JSP, JSTL, MVC, Servlet Wit
h 9 comments
Este post vai apresentar como implementar um upload e download de arquivos usand
o Servlets, JSP, JSTL, EL e o padro MVC.
Para este exemplo, vou criar um projeto web dinmico no Eclipse. Eu no vou especifi
car um banco de dados, o cdigo deve funcionar com qualquer banco relacional.
Para implementar o exemplo precisamos de quatro bibliotecas adicionais, sendo du
as da Apache:
http://commons.apache.org/fileupload/
http://commons.apache.org/io
E para usar o JSTL precisamos de mais duas bibliotecas adicionais, a API e a imp
lementao. Ambos podem ser encontrados no link:
http://jstl.java.net/download.html
Baixe todas as bibliotecas e adicione na pasta lib dentro de WebContent. A pasta
lib tambm deve conter o conector para o banco de dados utilizado.
Upload
A pgina de envio deve conter um formulrio com os campos necessrios e mais um campo
de input type file para o upload. No exemplo a seguir, vou mostrar o formulrio co
m apenas dois campos: input type="file" e outro input type="text".
<form action="upload.do" enctype="multipart/form-data" method="post">
<label for="desc">Descrio:</label>
<input type="text" name="desc" id="desc"><br/>
<label for="file">Arquivo:</label>
<input type="file" name="file" id="file"><br/>
<input type="submit" value="Enviar"/>
</form>
A servlet que vai receber os dados deste formulrio deve conter o cdigo:
public class UploadFileServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
DiskFileItemFactory dfif = new DiskFileItemFactory();
ServletFileUpload sfu = new ServletFileUpload(dfif);
if (!ServletFileUpload.isMultipartContent(req)) {
// tratar erro
}
try {
List items = sfu.parseRequest(req);
//a posicao 0 corresponde ao primeiro campo input do formulario (des

cricao)
FileItem descFI = (FileItem) items.get(0);
String desc = descFI.getString();
//a posicao 1 corresponde ao segundo campo input do formulario (arqu
ivo)
FileItem fileFI = (FileItem) items.get(1);
byte[] bytes = read(fileFI);
//No o File do Java. um JavaBean apresentado a seguir
FileBean filebean = new FileBean();
filebean.setDescription(fileFI.getDesc());
filebean.setName(fileFI.getName());
filebean.setData(bytes);
FileDao fdao = new FileDaoImpl();
fdao.add(filebean);
} catch (FileUploadException e) {
// tratar erro
}
resp.sendRedirect("list.jsp");
}
private byte[] read(FileItem fi) throws IOException{
ByteArrayOutputStream out = new ByteArrayOutputStream();
InputStream is = fi.getInputStream();
int read = 0;
final byte[] b = new byte[1024];
while ((read = is.read(b)) != -1) {
out.write(b, 0, read);
}
return out.toByteArray();
}
}
Para verificar se um FileItem um campo do comum formulrio ou um campo (input) do
tipo file, podemos usar o mtodo: fileItem.isFormField().
No se esquea de mapear a sua servlet (UploadFileServlet)! Pode ser mapeada usando
anotaes (API Servlet 3.x) ou com o bom e velho deployment descriptor (web.xml). Se
gue o trecho do web.xml correspondente:
<servlet>
<servlet-name>UploadFileServlet</servlet-name>
<servlet-class>controller.user.file.UploadFileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UploadFileServlet</servlet-name>
<url-pattern>/upload.do</url-pattern>
</servlet-mapping>
No cdigo acima a classe da servlet se encontra no pacote controller.user.file , a
ltere para o caminho correto dentro da sua aplicao.
A servlet UploadFileServlet faz uso da classe JavaBean FileBean, com o cdigo:

public class FileBean {


private String description;
private String name;
private Long id;
private byte[] data;
public FileBean() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
}
Para armazenar o cdigo no banco de dados temos que ter uma tabela que corresponda
ao arquivo. Essa tabela deve conter um varchar para o nome, outro para a descrio,
um campo blob para o arquivo (bytes) e um campo id para identificar cada arquiv
o adicionado. Devemos setar esse ltimo campo como autoincrement (MySQL).
O cdigo da DAO que armazena os dados, lista e busca o JavaBean (FileBean) no banc
o de dados :
public boolean add(FileBean filebean) {
int added = 0;
try {
Connection con = ConnectionFactory.createConnection();
if (con != null) {
String sql = "INSERT INTO file (name, description, data) VALUES
(?, ?, ?)";
PreparedStatement st = con.prepareStatement(sql);
st.setString(1, filebean.getName());

st.setString(2, filebean.getDescription());
st.setBytes(3, filebean.getData());
added = st.executeUpdate();
st.close();
con.close();
}
} catch (SQLException e) {
//tratar erro
}
return added > 0;
}
public List list() {
List files = new ArrayList();
try {
Connection con = ConnectionFactory.createConnection();
if (con != null) {
String sql = "SELECT * FROM file";
Statement st = con.createStatement();
ResultSet rs = st.execute(sql);
while(rs.next()){
FileBean filebean = createFileBean(rs);
files.add(filebean);
}
st.close();
con.close();
}
} catch (SQLException e) {
//tratar erro
}
return files;
}
public FileBean getFile(long id) {
FileBean filebean = null;
try {
Connection con = ConnectionFactory.createConnection();
if (con != null) {
String sql = "SELECT * FROM file WHERE id=?";
PreparedStatement st = con.prepareStatement(sql);
st.setLong(1, id);
ResultSet rs = st.executeQuery();
if (rs.next()) {
filebean = createFileBean(rs);
}
rs.close();
st.close();
con.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
return file;
}
private FileBean createFileBean(ResultSet rs) throws SQLException {

FileBean filebean = new FileBean();


filebean.setData(rs.getBytes("data"));
filebean.setId(rs.getLong("id"));
filebean.setName(rs.getString("name"));
filebean.setDescription(rs.getString("description"));
return filebean;
}
Os mtodos da DAO fazem chamada a um mtodo da classe ConnectionFactory que apenas c
ria e retorna uma conexo ao banco de dados. Daqui j podemos executar pra testar!
Download
Para o download vou mostrar um trecho de cdigo de um JSP (list.jsp) que lista os
arquivos do banco de dados e ao clicar sobre um arquivo o download iniciado. Est
e cdigo faz uso do JSTL e da EL. Se for uma imagem ele mostra um thumbnail ao invs
do boto de download.
<table>
<thead>
<tr>
<th align="center"><b>Nome</b></th>
<th align="center"><b>Descrio</b></th>
<th align="center"><b>Arquivo</b></th>
</tr>
</thead>
<tbody>
<c:forEach var="file" items="${items}">
<c:set value="${fn:endsWith(file.name, 'jpg') or fn:endsWith(fil
e.name, 'png')}" var="isImage"/>
<tr>
<td>${file.name}</td>
<td>${file.description}</td>
<c:if test="${isImage}">
<td><img width="50" height="50" src="download.do?id=${fi
le.id}"/></td>
</c:if>
<c:if test="${not isImage}">
<td><a href="download.do?id=${file.id}">Baixar</a></td>
</c:if>
</tr>
</c:forEach>
</tbody>
</table>
A servlet que busca os arquivos na base de dados tem o cdigo:
public class ListFilesServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
FileDao dao = new FileDaoImpl();
List<FileBean> files = dao.list();

req.setAttribute("items", dao.list());
RequestDispatcher rd = pReq.getRequestDispatcher("list.jsp");
rd.forward(req, resp);
}
}
A classe da servlet responsvel pelo download tem o cdigo:
public class DownloadFileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String idStr = req.getParameter("id");
if(idStr == null){
//redirect to home or other
}
FileDao dao = new FileDaoImpl();
Long id = Long.parseLong(idStr);
FileBean filebean = dao.getFile(id);
if (file != null) {
ServletContext context = getServletConfig().getServletContext();
String mimetype = context.getMimeType(filebean.getName());
resp.setContentLength(filebean.getData().length);
resp.setContentType(mimetype);//resp.setContentType("image/jpeg");
resp.setHeader("Content-Disposition", "attachment; filename=\"" +
filebean.getName() + "\"");
OutputStream out = resp.getOutputStream();
InputStream in = new ByteArrayInputStream(filebean.getData());
byte[] buffer = new byte[4096];
int length;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
in.close();
out.flush();
}
}
}
Elas tambm devem ser mapeadas, tal como no exemplo a seguir:
<servlet>
<servlet-name>DownloadFileServlet</servlet-name>
<servlet-class>controller.user.file.DownloadFileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DownloadFileServlet</servlet-name>
<url-pattern>/download.do</url-pattern>
</servlet-mapping>

<servlet>
<servlet-name>ListFilesServlet</servlet-name>
<servlet-class>controller.user.file.ListFilesServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ListFilesServlet</servlet-name>
<url-pattern>/list.do</url-pattern>
</servlet-mapping>
Acho que isso. Se tiver algum erro, melhoria ou dificuldade na implementao s avisar
!
Happy coding!
[]`s
Share This:
Facebook
Twitter
Google+
Stumble
Digg
Enviar por e-mailBlogThis!Compartilhar no TwitterCompartilhar no Facebook
Related Posts:
Como fazer upload e download de arquivos usando Servlet e JSPEste post vai a
presentar como implementar um upload e download de arquivos usando Servlets, JSP
, JSTL, EL e o padro MVC. Para este exemplo, vou cria Mais
Postagem mais recente Pgina inicial
9 comentrios:
Marcos Fabris17 de maio de 2013 10:06
Ol muito boa sua explicao
Porm estou com um problema, eu preciso usar no meu form um tipo hidden. E usa
ndo esse enctype eu no to conseguindo.
Sabe algum jeito de resolver isso ?
Desde j grato
Marcos Fabris
Responder
Respostas
Anderson Vioso de Arajo17 de maio de 2013 10:47
Marcos, fiz um teste aqui e verifiquei que funciona normalmente como se
fosse um campo do tipo "text", como no exemplo da descrio. Acho que o problema dev
e ser outro.
[]s
Responder
Unknown19 de maio de 2013 14:18
Ol Anderson, muito boa sua explicao, s no consegui entender como fazer o upload d
e arquivos grandes, como crio um buffer? teria algum material?
Muito obrigado

Responder
Respostas
Anderson Vioso de Arajo19 de maio de 2013 15:04
Alterei o cdigo do exemplo para possibilitar o upload de arquivos de qual
quer tamanho.
[]s
Responder
Unknown19 de maio de 2013 15:17
Muito obrigado Anderson :)
Helder Weber Gayer
Responder
Douglas3 de dezembro de 2013 04:50
Consegui salvar a imagem no entanto no consigo a recuperar, no meu projeto te
nho que usar jsp puro, no posso colocar jstl.
Voc pode me ajudar?
Responder
Respostas
Anderson Vioso de Arajo3 de dezembro de 2013 07:03
Ol Douglas,
Para fazer o download ou exibir a imagem sem o JSTL e EL s trocar o cdigo
para um cdigo com scripts (scriptlets, expresses, declaraes JSP) correspondente. Por
exemplo: a tag c:forEach deve ser trocada por um <% for(File file: request.getAt
tribute("items")) ... %>. J a tag c:if deve ser trocada por um <% if( ... ) %> e
assim por diante.
[]s
Responder
Marcos Rodrigues22 de setembro de 2015 11:58
Ol Anderson,
Gostaria de uma dica se possivel, nosso sistema tem a misso de fazer upload d
e muitas imagens, e tambem ter uma campo de busca de imagens, essa busca de imag
ens seria assim, primeiro colocariamos o numero que faz referencia a um determin
ado registro e este registro iria puxar e exibir a imagem para o usuario, kara,
so muitos registros e muitas imagens, muitas um numero que iria aumentando gradat
ivamente todos os dias, e este servidor com as imagens seria acessado por varias
maquinas, kara, vc tem alguma dica onde posso pesquisar algo do tipo, e qual pr
ocesso de upload nao iria pesar o sistema? uma dica, por favor? Agradecido
Responder
Respostas
Anderson Vioso de Arajo28 de setembro de 2015 16:02
Ol Marcos,
No sei se entendi direito, mas o upload que eu mostrei vai enviar a image
m para o servidor e vai guardar no BD. claro que depois de um tempo, o BD vai au
mentando sim. Existe a possibilidade de enviar vrias imagens de uma vez atravs do
atributo multiple da tag input. S que voc tem que ler corretamente do lado servido
r.
No entendi corretamente a parte do sistema com a busca de imagens. Precis
o de mais informaes, so muitos detalhes.
Um abrao.

Responder