Upload de arquivo utilizando Servlet 3
Em versões mais antigas do Servlet tínhamos que apelar para APIs externas para realizar o upload de arquivos no java, agora com Servlet 3 o trabalho ficou mais fácil.
Para começar vamos ao formulário, não esquecendo do enctype="multipart/form-data"
para o arquivo ser enviado junto com a requisição.
<form method="POST" action="/upload/UploadServlet" enctype="multipart/form-data">
<div class="input">
<label>Upload</label>
<input type="file" name="arquivo">
</div>
<input type="submit" value="Enviar">
</form>
MultipartConfig Annotation
Par a lidar com requisições multipart/form-data devemos anotar o Servlet
com a anotação @MultipartConfig
e configurar seus atributos com as configurações de upload.
- MaxFileSize: Especifica o tamanho máximo de cada arquivo que será aceito. O tamanho é especificado em bits, então 1024 * 1024 * 5 = 10MB.
- location: O diretório temporário em que os arquivos enviados serão armazenados para processamento. O valor padrão é “”.
- maxRequestSize: Especifica o tamanho total máximo permitido da requisição
multipart/form-data
. O valor padrão é -1L que seria ilimitado. - fileSizeThreshold: Se o tamanho de um arquivo for superior a este limite ele será gravado em disco, em vez de guardar na memória;
@WebServlet("/UploadServlet")
@MultipartConfig(
fileSizeThreshold = 1024 * 1024, // 1MB
maxFileSize = 1024 * 1024 * 4, // 4MB
maxRequestSize = 1024 * 1024 * 4 // 4MB
)
public class UploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public UploadServlet() {
// TODO Auto-generated constructor stub
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//aqui manipulamos o arquivo recebido
}
}
Para pegarmos os arquivos envidados pelo formulário utilizamos os métodos request.getParts()
que retorna uma Collection
de Part
com todos os arquivos envidados pelo formulário ou request.getPart(String name)
que retorna o Part
do arquivo enviado com o name passado por parâmetro.
A classe Part
representa o arquivo enviado pela requisição e possui os seguintes métodos:
- getName(): Retorna o name do campo input do formulário em que foi envidado o arquivo.
- getSize(): Retorna o tamanho do arquivo em bytes.
- getContentType(): Retorna o tipo do arquivo enviado. Ex.: application/pdf, image/png, text/plain.
- getHeaderNames(): Retorna uma Collection com todos os nomes dos header da Part
- getHeader( String name ) Dado o nome de um header retorna o valor do header. Ex.: getHeader(“content-disposition”) retorna “form-data; name=”arquivo”; filename=”documento.pdf”.
- getInputStream(): Retorna um InputStream para leitura do arquivo enviado.
- write( String fileName ): Grava o arquivo enviado no local passado por parâmetro.
Se você deve ter notado diferente de outras linguagem não temos um método direto para pegar o nome do arquivo, mas o nome do arquivo está no header “content-disposition“, então podemos quebrar esta String para pegar o nome do arquivo, vamos ao método que dado um Part
retorna o nome do arquivo.
public String getFileName(Part part){
String header = part.getHeader( "content-disposition" );
for( String tmp : header.split(";") ){
if( tmp.trim().startsWith("filename") ){
return tmp.substring( tmp.indexOf("=")+2 , tmp.length()-1 );
}
}
return null;
}
Agora um exemplo do método doPost
.
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
File dir = new File( getServletContext().getRealPath("uploads") );// diretório de upload
//se o diretório não existe ele cria
if( !dir.isDirectory() ){
dir.mkdir();
}
for(Part part: request.getParts()){
response.getWriter().println("=========================================================");
response.getWriter().println("Name do campo file: "+part.getName() );
response.getWriter().println("Tamanho: "+part.getSize()+" bytes" );
response.getWriter().println("Content type: "+part.getContentType() );
response.getWriter().println( "Nome do arquivo: " + this.getFileName(part) );
for(String headerName : part.getHeaderNames()){
response.getWriter().println("---------------------------------------------" );
response.getWriter().println("Header name: "+ headerName );
response.getWriter().println( part.getHeader( headerName ) );
response.getWriter().println("---------------------------------------------" );
}
//grava o arquivo no disco
File arquivo = new File( dir.getAbsolutePath() + "/" + getFileName(part) );
part.write( arquivo.getAbsolutePath() );
response.getWriter().println("=========================================================");
}
}
Bom era isso, espero ter ajudado.