Solucionado (ver solução)
Solucionado
(ver solução)
5
respostas

Download de arquivos com Spring MVC

No curso foi apresentado como fazer o upload de arquivo com o spring mvc, qual o procedimento para download de arquivos?

5 respostas

Fala aí Rhelcris, blz?

Para fazer o download você precisa no seu controller retornar um HttpEntity<byte[]> e passar o header Content-Disposition.

@RequestMapping(method = RequestMethod.GET)    
public HttpEntity<byte[]> download(String token) {

    byte[] arquivo = //pega os bytes de qualquer arquivo
    HttpHeaders httpHeaders = new HttpHeaders();

    httpHeaders.add("Content-Disposition", "attachment;filename=\""+NOME_DO_ARQUIVO_QUE_SERÁ_BAIXADO+"\"");

    HttpEntity<byte[]> entity = new HttpEntity<byte[](arquivo,httpHeaders);

   return entity;
    }

Aqui tem um post no blog domineospring que fala mais detalhes sobre isso => https://domineospring.wordpress.com/2015/05/25/download-de-arquivos-no-spring-mvc/

Bom dia,

Obrigado pela resposta porém não consegui com o código que você me enviou fazer o download do arquivo, com o código a seguir eu consegui abrir no navegador .. porém abre na mesma aba do meu navegador ... você sabe como eu posso fazer para abrir em uma nova aba?

@RequestMapping(method = RequestMethod.GET, value = "/download/{fileName}")
    public void download(HttpServletResponse response, @PathVariable("fileName") String fileName) {
        String path = servletContext.getRealPath("/upload/");
        Path arquivo = Paths.get(path, fileName + ".pdf");

        if(Files.exists(arquivo)) {
            response.setHeader("Content-Disposition", "inline");
            response.setContentType("application/pdf");            
            try {
                Files.copy(arquivo, response.getOutputStream());
                response.getOutputStream().flush();
            } 
            catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

Qual o problema que você enfrentou ao utilizar o primeiro código?

Quando você passa o inline no Content-Disposition ele pede para o navegador abrir o documento. (O que acaba acontecendo na mesma aba).

O que você pode fazer é no link que leva o usuário até esse controller você colcoar target="_blank" isso irá forçar o navegador a abrir uma nova aba ou janela (dependendo do browser).

No caso da minha aplicação eu gravo os meus pdf e disponibilizo opções para o usuário abrir em uma nova aba do navegador e para download.

Utilizando aquele código que envie anteriormente consigo abrir o pdf, utilizei o target="_blank" no meu href e abriu em outra aba perfeito.

Agora estou fazendo a parte para download do arquivo. Minha dúvida é: no seu código vc usa um array de bytes como eu jogo meu arquivo no array de bytes?

byte[] arquivo = //pega os bytes de qualquer arquivo
 HttpHeaders httpHeaders = new HttpHeaders();

Como transformar meu arquivo em byte? Pois eu carrego meu arquivo da seguinte forma.

String path = servletContext.getRealPath("/upload/");
Path arquivo = Paths.get(path, fileName + ".pdf");

Ou seja estou utilizando OutputStream e vc byte[].

Se observar no meu primeiro código eu faço da seguinte forma

httpHeaders.add("Content-Disposition", "attachment;filename=\""+fileName+"\"");

Files.copy(arquivo, response.getOutputStream());
response.getOutputStream().flush();

Qual método é melhor para baixar grandes arquivos usando byte ou OutputStream? pois já vi alguns comentários em foruns sobre o assunto.

solução!

Consegui colocar o arquivo para abrir e para download. Vou deixar os códigos caso alguém tenha as mesmas dúvidas.

Código para abrir o arquivo no navegador ... os nomes dos métodos estão trocados porém depois arrumo.

@RequestMapping(method = RequestMethod.GET, value = "/download/{fileName}")
    public void download(HttpServletResponse response, @PathVariable("fileName") String fileName) {
        String path = servletContext.getRealPath("/upload/");
        Path arquivo = Paths.get(path, fileName + ".pdf");        

        if(Files.exists(arquivo)) {   //inline
            response.setHeader("Content-Disposition", "inline");
            response.setContentType("application/pdf");

            try {
                Files.copy(arquivo, response.getOutputStream());
                response.getOutputStream().flush();
            } 
            catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

Agora para fazer o download dos arquivos

@RequestMapping(value = "/files/{file_name}", method = RequestMethod.GET)
    public void getFile(@PathVariable("file_name") String fileName, HttpServletResponse response) {
        String path = servletContext.getRealPath("/upload/");
        Path arquivo = Paths.get(path, fileName + ".pdf");

        if (Files.exists(arquivo)) 
        {
            response.setContentType("application/pdf");
            response.addHeader("Content-Disposition", "attachment; filename=\"" + fileName +".pdf" + "\"");
            try {
                Files.copy(arquivo, response.getOutputStream());
                response.getOutputStream().flush();
            } 
            catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }