Integração do Front-end com Uploadifive
O Uploadiifve é uma ferramenta robusta baseada em HTML5 para a gestão de uploads de arquivos, oferecendo compatibiliddae tanto para ambientes desktop quanto mobile. Sua implementação substitui versões legadas baseadas em Flash, proporcionando uma experiência de usuário mais fluida.
Para iniciar a integração, é necessário referenciar os arquivos da biblioteca no projeto e prepaarr o elemento de entrada no HTML:
<!-- Estrutura básica HTML -->
<div class="upload-container">
<input id="input_documento" type="file" name="input_documento" />
</div>
A configuração do script via jQuery define o comportamento do upload e aponta para o endpoint do servidor:
$('#input_documento').uploadifive({
'uploadScript': '/SistemaGestao/processar-upload',
'buttonText': 'Selecionar Arquivo',
'height': 40,
'width': 150,
'fileSizeLimit': '10MB',
'multi': true,
'onUploadComplete': function(file, response) {
console.log('O arquivo ' + file.name + ' foi processado com sucesso.');
alert('Resposta do servidor: ' + response);
}
});
O atributo uploadScript é fundamental, pois define a URL que processará os dados binários. Neste cenário, utilizaremos um Servlet Java para atuar como o receptor desses dados.
Arquitetura e Funcionamento do Servlet
Um Servlet é um componente Java que reside no lado do servidor e gerencia requisições HTTP. Ele atua como uma camada intermediária entre o cliente (browser) e a lógica de negócios ou banco de dados. Quando o Uploadifive dispara uma requisição POST, o Servlet intercepta esses dados, processa o fluxo de bytes e os armazena no sistema de arquivos ou banco de dados conforme a necessidade.
Configuração do Descritor de Implantação (web.xml)
Para que o servidor de aplicação reconheça o Servlet, é necessário mapeá-lo no arquivo web.xml. O url-pattern deve coincidir exatamente com o valor definido no uploadScript do front-end.
<servlet>
<servlet-name>FileHandlerServlet</servlet-name>
<servlet-class>br.com.projeto.servlet.FileHandlerServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FileHandlerServlet</servlet-name>
<url-pattern>/processar-upload</url-pattern>
</servlet-mapping>
Implementação do Backend com Apache Commons FileUpload
Para processar multipart/form-data de forma eficiente, utilizamos as bibliotecas commons-fileupload e commons-io. Abaixo, apresentamos uma implementação otimizada do Servlet para gerenciar o armazenamento dos arquivos.
package br.com.projeto.servlet;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;
public class FileHandlerServlet extends HttpServlet {
private static final long serialVersionUID = 1029384756L;
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
// Define o diretório de destino
String storagePath = getServletContext().getRealPath("/arquivos_enviados");
File uploadDir = new File(storagePath);
if (!uploadDir.exists()) uploadDir.mkdir();
// Configuração da fábrica de itens de arquivo
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(1024 * 1024 * 2); // 2MB de buffer em memória
factory.setRepository(new File(System.getProperty("java.io.tmpdir")));
ServletFileUpload uploadProcessor = new ServletFileUpload(factory);
try {
List<FileItem> items = uploadProcessor.parseRequest(req);
for (FileItem item : items) {
if (!item.isFormField()) {
// Extração do nome do arquivo de forma segura
String fileName = new File(item.getName()).getName();
File storeFile = new File(storagePath + File.separator + fileName);
// Transferência dos dados para o disco
try (InputStream input = item.getInputStream();
OutputStream output = new FileOutputStream(storeFile)) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = input.read(buffer)) != -1) {
output.write(buffer, 0, bytesRead);
}
}
System.out.println("Arquivo salvo em: " + storeFile.getAbsolutePath());
}
}
} catch (Exception e) {
resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
e.printStackTrace();
}
}
}
Considerações de Segurança e Concorrência
Ao trabalhar com Servlets, é vital lembrar que eles são singletons por padrão dentro do container web. Isso significa que uma única instância do Servlet atende a múltiplas requisições simultâneas. Para garantir o thread-safety, evite o uso de variáveis de instância para armazenar dados específicos de uma requisição. No exemplo acima, todas as variáveis críticas (como caminhos e fluxos de dados) são definidas localmente dentro do método doPost, garantindo que cada thread de execução possua seu próprio escopo.