2015-10-07 81 views
1

我目前正在使用jQuery和Spring Rest。 jQuery被用来上传和下载文件到服务器。上传过程正常,但我没有下载文件的问题。因此,在该视图中,用户将选择要下载的n个文件并单击下载按钮。一旦用户点击该按钮,文件将被下载。我不想为每个文件下载打开一个新的新选项卡。我想在不刷新当前视图的情况下在同一窗口下载。我看着this,但没有多大帮助。有什么办法,我可以做到这一点?Spring Rest和jQuery Ajax文件下载

回答

0

这里是我的解决方案,以下载文件:

春控制器的方法:

@RequestMapping(value = "/download", method = RequestMethod.GET) 
public void retrieveDocument(@RequestParam("id") String id, HttpServletResponse response) throws IOException { 
    InputStream in = fileService.getFileStream(); // My service to get the stream. 
    response.setContentType(MediaType.APPLICATION_OCTET_STREAM); 
    response.setHeader("Content-Transfer-Encoding", "binary"); 
    response.setHeader("Content-Disposition", "attachment; filename=" + filename); 
    try { 
     IOUtils.copy(inputStream, response.getOuputStream()); //Apache commons IO. 
     inputStream.close(); 
     response.flushBuffer(); 
     response.setStatus(HttpServletResponse.SC_OK); 
    } catch (Exception e) { 
     //log error. 
    } 

}

在客户端功能:

function download(id) { 
    var id = $('#file').attr('id') 
    var xhr = new XMLHttpRequest(); 
    xhr.open('GET', 'url here' + id, true); 
    xhr.responseType = 'arraybuffer'; 
    xhr.onload = function() { 
     if(this.status == '200') { 
      var filename = ''; 
      //get the filename from the header. 
      var disposition = xhr.getResposeHeader('Content-Disposition'); 
      if (disposition && disposition.indexOf('attachment') !== -1) { 
       var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/; 
       var matches = filenameRegex.exec(disposition); 
       if (matches !== null && matches[1]) 
        filename = matches[1].replace(/['"]/g, ''); 
      } 
      var type = xhr.getResponseHeader('Content-Type'); 
      var blob = new Blob([this.response], {type: type}); 
      //workaround for IE 
      if(typeof window.navigator.msSaveBlob != 'undefined') { 
       window.navigator.msSaveBlob(blob, filename); 
      } 
      else { 
       var URL = window.URL || window.webkitURL; 
       var download_URL = URL.createObjectURL(blob); 
       if(filename) { 
        var a_link = document.createElement('a'); 
        if(typeof a.download == 'undefined') { 
         window.location = download_URL; 
        }else { 
         a_link.href = download_URL; 
         a_link.download = filename; 
         document.body.appendChild(a_link); 
         a_link.click(); 
        } 
       }else { 
        window.location = download_URL; 
       } 
       setTimeout(function() { 
        URL.revokeObjectURL(download_URL); 
       }, 10000); 
      } 
     }else { 
      alert('error')';//do something... 
     } 
    }; 
    xhr.setRequestHeader('Content-type', 'application/*'); 
    xhr.send(); 
} 
1

我回答类似的东西在几分钟前:我建议你使用这个JS插件https://github.com/johnculviner/jquery.fileDownload下载使用,而不是直接$就文件sending file from response to user, Spring REST + jQuery


。你可以在那里找到所有的官方文档。

而且,在你的控制器,你得把你的HttpServletResponse谱写OutputStream的字节[],你必须把一个cookie的响应通知JS插件(因为它需要它)

例如:

@RequestMapping(value = "/download", method = RequestMethod.GET) 
    public void getFilesInZIP(@RequestParam("filenames[]") String[] filenames, HttpServletResponse httpServletResponse){ 
     byte[] file = service.packFilesToZIPArchiveAndReturnAsByteArray(filenames); 

     Cookie cookie = new Cookie("fileDownload", "true"); 
     cookie.setPath("/"); 

     httpServletResponse.addCookie(cookie); 
     httpServletResponse.setContentType("application/zip"); 
     httpServletResponse.setHeader("Content-Disposition", "attachment;filename=files.zip"); 
     httpServletResponse.getOutputStream().write(file); 

    } 
+0

虽然此链接可以回答这个问题,最好是在这里有答案的主要部件,并提供链接以供参考。如果链接页面更改,则仅链接答案可能会失效。 - [来自评论](/ review/low-quality-posts/10266851) –

+0

这是另一个线程中的另一个问题。我更愿意给他与我的答案的链接,而不是复制+粘贴 – Roman

+0

了解。不过,我们通常尽量避免在StackOverflow中使用仅链接的答案。 (这里有一些[相关讨论](http://meta.stackexchange.com/questions/8231/are-answers-that-just-contain-links-elsewhere-really-good-answers)。)链接在一个完美的罚款评论,或者你可以尝试提炼答案的关键点以及链接。 –